home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 84 / CD-ROM 84 / CD-ROM 84.iso / jogos / circus / circuslinux.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-29  |  74.5 KB  |  3,756 lines

  1. /*
  2.   circuslinux.c
  3.   
  4.   Circus Linux!
  5.   
  6.   A clone of the Atari 2600 game "Circus Atari."
  7.   (Similar to "Breakout" and "Arkanoid.")
  8.  
  9.   Use a teeter-totter to bounce clowns up in the air to pop balloons.
  10.   
  11.   by Bill Kendrick
  12.   bill@newbreedsoftware.com
  13.   http://www.newbreedsoftware.com/
  14.   
  15.   December 11, 1999 - May 29, 2000
  16. */
  17.  
  18.  
  19. /* Constraints: */
  20.  
  21. #define NUM_TITLE_BALLOONS 16
  22. #define STARTING_LIVES 5
  23. #define MAX_RECTS 512
  24. #define FLYING_START_Y 192
  25. #define FLYING_START_YM -8
  26. #define BOUNCER_TIME 6
  27. #define GRAVITY 1
  28. #define FLYING_SPLAT_TIME 50
  29. #define NUM_ROWS 3
  30. #define NUM_BARRIERS 3
  31. #define FASTEST_YM_OFF_BALLOON 8
  32. #define MAX_YM 32
  33. #define LIMB_ANIMATION_TIME 8
  34. #define FPS (1000 / 33)
  35. #define SHOW_PLAYER_TIME 100
  36.  
  37.  
  38. /* Definitions: */
  39.  
  40. #define LEFT  0
  41. #define RIGHT 1
  42.  
  43. #define GONE 0
  44. #define NORMAL 1
  45. #define POPPING0 2
  46. #define POPPING1 2
  47.  
  48.  
  49. /* #includes: */
  50.  
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <errno.h>
  55. #include <unistd.h>
  56. #include <SDL.h>
  57. #include <SDL_image.h>
  58.  
  59. #ifndef NOSOUND
  60. #include <SDL_mixer.h>
  61. #endif
  62.  
  63. #ifdef LINUX
  64. #include <pwd.h>
  65. #include <sys/types.h>
  66. #include <ctype.h>
  67. #endif
  68.  
  69.  
  70. /* Image enumerations: */
  71.  
  72. enum {
  73.   IMG_TITLE,
  74.   IMG_TITLE_HIGHLIGHTS,
  75.   IMG_LIGHT_ON,
  76.   IMG_LIGHT_OFF,
  77.   IMG_PROGRAMMER,
  78.   IMG_GRAPHICS,
  79.   IMG_MUSIC,
  80.   
  81.   IMG_BACKGROUND_0,
  82.   IMG_BACKGROUND_1,
  83.   
  84.   IMG_BALLOON_RED_LEFT_0,
  85.   IMG_BALLOON_RED_LEFT_1,
  86.   IMG_BALLOON_RED_RIGHT_0,
  87.   IMG_BALLOON_RED_RIGHT_1,
  88.   IMG_BALLOON_RED_DIE_0,
  89.   IMG_BALLOON_RED_DIE_1,
  90.  
  91.   IMG_BALLOON_ORANGE_LEFT_0,
  92.   IMG_BALLOON_ORANGE_LEFT_1,
  93.   IMG_BALLOON_ORANGE_RIGHT_0,
  94.   IMG_BALLOON_ORANGE_RIGHT_1,
  95.   IMG_BALLOON_ORANGE_DIE_0,
  96.   IMG_BALLOON_ORANGE_DIE_1,
  97.  
  98.   IMG_BALLOON_YELLOW_LEFT_0,
  99.   IMG_BALLOON_YELLOW_LEFT_1,
  100.   IMG_BALLOON_YELLOW_RIGHT_0,
  101.   IMG_BALLOON_YELLOW_RIGHT_1,
  102.   IMG_BALLOON_YELLOW_DIE_0,
  103.   IMG_BALLOON_YELLOW_DIE_1,
  104.  
  105.   IMG_BALLOON_GREEN_LEFT_0,
  106.   IMG_BALLOON_GREEN_LEFT_1,
  107.   IMG_BALLOON_GREEN_RIGHT_0,
  108.   IMG_BALLOON_GREEN_RIGHT_1,
  109.   IMG_BALLOON_GREEN_DIE_0,
  110.   IMG_BALLOON_GREEN_DIE_1,
  111.  
  112.   IMG_BALLOON_CYAN_LEFT_0,
  113.   IMG_BALLOON_CYAN_LEFT_1,
  114.   IMG_BALLOON_CYAN_RIGHT_0,
  115.   IMG_BALLOON_CYAN_RIGHT_1,
  116.   IMG_BALLOON_CYAN_DIE_0,
  117.   IMG_BALLOON_CYAN_DIE_1,
  118.  
  119.   IMG_BALLOON_BLUE_LEFT_0,
  120.   IMG_BALLOON_BLUE_LEFT_1,
  121.   IMG_BALLOON_BLUE_RIGHT_0,
  122.   IMG_BALLOON_BLUE_RIGHT_1,
  123.   IMG_BALLOON_BLUE_DIE_0,
  124.   IMG_BALLOON_BLUE_DIE_1,
  125.  
  126.   IMG_BALLOON_PURPLE_LEFT_0,
  127.   IMG_BALLOON_PURPLE_LEFT_1,
  128.   IMG_BALLOON_PURPLE_RIGHT_0,
  129.   IMG_BALLOON_PURPLE_RIGHT_1,
  130.   IMG_BALLOON_PURPLE_DIE_0,
  131.   IMG_BALLOON_PURPLE_DIE_1,
  132.  
  133.   IMG_BALLOON_WHITE_LEFT_0,
  134.   IMG_BALLOON_WHITE_LEFT_1,
  135.   IMG_BALLOON_WHITE_RIGHT_0,
  136.   IMG_BALLOON_WHITE_RIGHT_1,
  137.   IMG_BALLOON_WHITE_DIE_0,
  138.   IMG_BALLOON_WHITE_DIE_1,
  139.  
  140.   IMG_CLOWN_BODY_LEFT,
  141.   IMG_CLOWN_BODY_RIGHT,
  142.   
  143.   IMG_CLOWN_BODY_UPSIDE_DOWN,
  144.   
  145.   IMG_CLOWN_LEFT_ARM_0,
  146.   IMG_CLOWN_LEFT_ARM_1,
  147.   IMG_CLOWN_LEFT_ARM_2,
  148.  
  149.   IMG_CLOWN_RIGHT_ARM_0,
  150.   IMG_CLOWN_RIGHT_ARM_1,
  151.   IMG_CLOWN_RIGHT_ARM_2,
  152.  
  153.   IMG_CLOWN_LEFT_LEG_0,
  154.   IMG_CLOWN_LEFT_LEG_1,
  155.   
  156.   IMG_CLOWN_LEFT_LEG_0_UPSIDE_DOWN,
  157.   IMG_CLOWN_LEFT_LEG_1_UPSIDE_DOWN,
  158.  
  159.   IMG_CLOWN_RIGHT_LEG_0,
  160.   IMG_CLOWN_RIGHT_LEG_1,
  161.   
  162.   IMG_CLOWN_RIGHT_LEG_0_UPSIDE_DOWN,
  163.   IMG_CLOWN_RIGHT_LEG_1_UPSIDE_DOWN,
  164.   
  165.   IMG_TEETER_TOTTER_LEFT_0,
  166.   IMG_TEETER_TOTTER_LEFT_1,
  167.   IMG_TEETER_TOTTER_LEFT_2,
  168.   IMG_TEETER_TOTTER_LEFT_3,
  169.  
  170.   IMG_TEETER_TOTTER_RIGHT_0,
  171.   IMG_TEETER_TOTTER_RIGHT_1,
  172.   IMG_TEETER_TOTTER_RIGHT_2,
  173.   IMG_TEETER_TOTTER_RIGHT_3,
  174.   
  175.   IMG_BOUNCER_0,
  176.   IMG_BOUNCER_1,
  177.   IMG_BARRIER,
  178.   
  179.   IMG_TIMES,
  180.   IMG_NUMBERS_0,
  181.   IMG_NUMBERS_1,
  182.   IMG_LETTERS,
  183.   IMG_FUZZ,
  184.   IMG_CLOWN_HEAD,
  185.   IMG_CLOWN_HEAD_OH,
  186.   IMG_SADCLOWN_0,
  187.   IMG_SADCLOWN_1,
  188.   IMG_SADCLOWN_2,
  189.   IMG_ENTER_INITIALS,
  190.   
  191.   IMG_HIGHSCORE_TOP,
  192.   IMG_HIGHSCORE_LEFT,
  193.   
  194.   IMG_SEAL_0,
  195.   IMG_SEAL_1,
  196.   
  197.   IMG_BEACHBALL_0,
  198.   IMG_BEACHBALL_1,
  199.   IMG_BEACHBALL_2,
  200.   
  201.   IMG_BEAR_RIGHT_0,
  202.   IMG_BEAR_RIGHT_1,
  203.   
  204.   IMG_BEAR_LEFT_0,
  205.   IMG_BEAR_LEFT_1,
  206.   
  207.   NUM_IMAGES
  208. };
  209.  
  210.  
  211. /* Image fileames: */
  212.  
  213. const char * image_names[NUM_IMAGES] = {
  214.   DATA_PREFIX "images/title/title.png",
  215.   DATA_PREFIX "images/title/title-highlights.png",
  216.   DATA_PREFIX "images/title/light-on.png",
  217.   DATA_PREFIX "images/title/light-off.png",
  218.   DATA_PREFIX "images/title/programming.png",
  219.   DATA_PREFIX "images/title/graphics.png",
  220.   DATA_PREFIX "images/title/music.png",
  221.   
  222.   DATA_PREFIX "images/backgrounds/background0.png",
  223.   DATA_PREFIX "images/backgrounds/background1.png",
  224.   
  225.   DATA_PREFIX "images/balloons/red-left-0.png",
  226.   DATA_PREFIX "images/balloons/red-left-1.png",
  227.   DATA_PREFIX "images/balloons/red-right-0.png",
  228.   DATA_PREFIX "images/balloons/red-right-1.png",
  229.   DATA_PREFIX "images/balloons/red-die-0.png",
  230.   DATA_PREFIX "images/balloons/red-die-1.png",
  231.  
  232.   DATA_PREFIX "images/balloons/orange-left-0.png",
  233.   DATA_PREFIX "images/balloons/orange-left-1.png",
  234.   DATA_PREFIX "images/balloons/orange-right-0.png",
  235.   DATA_PREFIX "images/balloons/orange-right-1.png",
  236.   DATA_PREFIX "images/balloons/orange-die-0.png",
  237.   DATA_PREFIX "images/balloons/orange-die-1.png",
  238.  
  239.   DATA_PREFIX "images/balloons/yellow-left-0.png",
  240.   DATA_PREFIX "images/balloons/yellow-left-1.png",
  241.   DATA_PREFIX "images/balloons/yellow-right-0.png",
  242.   DATA_PREFIX "images/balloons/yellow-right-1.png",
  243.   DATA_PREFIX "images/balloons/yellow-die-0.png",
  244.   DATA_PREFIX "images/balloons/yellow-die-1.png",
  245.  
  246.   DATA_PREFIX "images/balloons/green-left-0.png",
  247.   DATA_PREFIX "images/balloons/green-left-1.png",
  248.   DATA_PREFIX "images/balloons/green-right-0.png",
  249.   DATA_PREFIX "images/balloons/green-right-1.png",
  250.   DATA_PREFIX "images/balloons/green-die-0.png",
  251.   DATA_PREFIX "images/balloons/green-die-1.png",
  252.  
  253.   DATA_PREFIX "images/balloons/cyan-left-0.png",
  254.   DATA_PREFIX "images/balloons/cyan-left-1.png",
  255.   DATA_PREFIX "images/balloons/cyan-right-0.png",
  256.   DATA_PREFIX "images/balloons/cyan-right-1.png",
  257.   DATA_PREFIX "images/balloons/cyan-die-0.png",
  258.   DATA_PREFIX "images/balloons/cyan-die-1.png",
  259.  
  260.   DATA_PREFIX "images/balloons/blue-left-0.png",
  261.   DATA_PREFIX "images/balloons/blue-left-1.png",
  262.   DATA_PREFIX "images/balloons/blue-right-0.png",
  263.   DATA_PREFIX "images/balloons/blue-right-1.png",
  264.   DATA_PREFIX "images/balloons/blue-die-0.png",
  265.   DATA_PREFIX "images/balloons/blue-die-1.png",
  266.  
  267.   DATA_PREFIX "images/balloons/purple-left-0.png",
  268.   DATA_PREFIX "images/balloons/purple-left-1.png",
  269.   DATA_PREFIX "images/balloons/purple-right-0.png",
  270.   DATA_PREFIX "images/balloons/purple-right-1.png",
  271.   DATA_PREFIX "images/balloons/purple-die-0.png",
  272.   DATA_PREFIX "images/balloons/purple-die-1.png",
  273.  
  274.   DATA_PREFIX "images/balloons/white-left-0.png",
  275.   DATA_PREFIX "images/balloons/white-left-1.png",
  276.   DATA_PREFIX "images/balloons/white-right-0.png",
  277.   DATA_PREFIX "images/balloons/white-right-1.png",
  278.   DATA_PREFIX "images/balloons/white-die-0.png",
  279.   DATA_PREFIX "images/balloons/white-die-1.png",
  280.   
  281.   DATA_PREFIX "images/clowns/body-left.png",
  282.   DATA_PREFIX "images/clowns/body-right.png",
  283.  
  284.   DATA_PREFIX "images/clowns/body-upside-down.png",
  285.   
  286.   DATA_PREFIX "images/clowns/left-arm-0.png",
  287.   DATA_PREFIX "images/clowns/left-arm-1.png",
  288.   DATA_PREFIX "images/clowns/left-arm-2.png",
  289.   
  290.   DATA_PREFIX "images/clowns/right-arm-0.png",
  291.   DATA_PREFIX "images/clowns/right-arm-1.png",
  292.   DATA_PREFIX "images/clowns/right-arm-2.png",
  293.   
  294.   DATA_PREFIX "images/clowns/left-leg-0.png",
  295.   DATA_PREFIX "images/clowns/left-leg-1.png",
  296.   
  297.   DATA_PREFIX "images/clowns/left-leg-0-upside-down.png",
  298.   DATA_PREFIX "images/clowns/left-leg-1-upside-down.png",
  299.   
  300.   DATA_PREFIX "images/clowns/right-leg-0.png",
  301.   DATA_PREFIX "images/clowns/right-leg-1.png",
  302.  
  303.   DATA_PREFIX "images/clowns/right-leg-0-upside-down.png",
  304.   DATA_PREFIX "images/clowns/right-leg-1-upside-down.png",
  305.   
  306.   DATA_PREFIX "images/teeter-totter/left-0.png",
  307.   DATA_PREFIX "images/teeter-totter/left-1.png",
  308.   DATA_PREFIX "images/teeter-totter/left-2.png",
  309.   DATA_PREFIX "images/teeter-totter/left-3.png",
  310.  
  311.   DATA_PREFIX "images/teeter-totter/right-0.png",
  312.   DATA_PREFIX "images/teeter-totter/right-1.png",
  313.   DATA_PREFIX "images/teeter-totter/right-2.png",
  314.   DATA_PREFIX "images/teeter-totter/right-3.png",
  315.  
  316.   DATA_PREFIX "images/bouncers/bouncer-0.png",
  317.   DATA_PREFIX "images/bouncers/bouncer-1.png",
  318.   DATA_PREFIX "images/bouncers/barrier.png",
  319.   
  320.   DATA_PREFIX "images/status/times.png",
  321.   DATA_PREFIX "images/status/numbers-0.png",
  322.   DATA_PREFIX "images/status/numbers-1.png",
  323.   DATA_PREFIX "images/status/letters.png",
  324.   DATA_PREFIX "images/status/fuzz.png",
  325.   DATA_PREFIX "images/status/clown-head.png",
  326.   DATA_PREFIX "images/status/clown-head-oh.png",
  327.   DATA_PREFIX "images/status/sadclown-0.png",
  328.   DATA_PREFIX "images/status/sadclown-1.png",
  329.   DATA_PREFIX "images/status/sadclown-2.png",
  330.   DATA_PREFIX "images/status/enter-initials.png",
  331.   
  332.   DATA_PREFIX "images/highscore/top.png",
  333.   DATA_PREFIX "images/highscore/left.png",
  334.  
  335.   DATA_PREFIX "images/acts/seal-0.png",
  336.   DATA_PREFIX "images/acts/seal-1.png",
  337.   
  338.   DATA_PREFIX "images/acts/beachball-0.png",
  339.   DATA_PREFIX "images/acts/beachball-1.png",
  340.   DATA_PREFIX "images/acts/beachball-2.png",
  341.  
  342.   DATA_PREFIX "images/acts/bear-right-0.png",
  343.   DATA_PREFIX "images/acts/bear-right-1.png",
  344.   DATA_PREFIX "images/acts/bear-left-0.png",
  345.   DATA_PREFIX "images/acts/bear-left-1.png"
  346. };
  347.  
  348.  
  349. /* Bits of background that change: */
  350.  
  351. #define NUM_BACKGROUND_CHANGES 4
  352.  
  353. int background_change_rects[NUM_BACKGROUND_CHANGES][4] = {
  354.   {424, 0, 88, 127},
  355.   {256, 150, 153, 87},
  356.   {26, 288, 57, 63},
  357.   {580, 295, 44, 55}
  358. };
  359.  
  360.  
  361. /* Acts: */
  362.  
  363. enum {
  364.   ACT_SEAL,
  365.   ACT_BEAR,
  366.   NUM_ACTS
  367. };
  368.  
  369.  
  370. /* Sound enumerations: */
  371.  
  372. enum {
  373.   SND_POP,
  374.   SND_BOUNCE,
  375.   SND_TEETER1,
  376.   SND_TEETER2,
  377.   SND_SPLAT,
  378.   SND_APPLAUSE,
  379.   SND_CHEERING,
  380.   SND_HIGHSCORE,
  381.   SND_KEYPRESS,
  382.   NUM_SOUNDS
  383. };
  384.  
  385.  
  386. /* Sound filenames: */
  387.  
  388. const char * sound_names[NUM_SOUNDS] = {
  389.   DATA_PREFIX "sounds/pop.wav",
  390.   DATA_PREFIX "sounds/bounce.wav",
  391.   DATA_PREFIX "sounds/teeter1.wav",
  392.   DATA_PREFIX "sounds/teeter2.wav",
  393.   DATA_PREFIX "sounds/splat.wav",
  394.   DATA_PREFIX "sounds/applause.wav",
  395.   DATA_PREFIX "sounds/cheering.wav",
  396.   DATA_PREFIX "sounds/wahoo.wav",
  397.   DATA_PREFIX "sounds/keypress.wav"
  398. };
  399.  
  400.  
  401. /* Music: */
  402.  
  403. #define MUS_TITLE DATA_PREFIX "music/finally.mod"
  404. #define MUS_GAME DATA_PREFIX "music/klovninarki.mod"
  405. #define MUS_GAMEOVER DATA_PREFIX "music/kaupunki.mod"
  406. #define MUS_HISCORE DATA_PREFIX "music/hiscore.mod"
  407. #define MUS_HISCORESCREEN DATA_PREFIX "music/hiscreen.mod"
  408.  
  409.  
  410. /* Local function prototypes: */
  411.  
  412. void setup(void);
  413. void intro(void);
  414. int title(void);
  415. int game(void);
  416. void erase(int x, int y, int w, int h, int bkgd);
  417. void draw(int x, int y, int pict);
  418. void drawclown(int x, int y, int side,
  419.            int left_arm, int right_arm,
  420.            int left_leg, int right_leg);
  421. void clearrects(void);
  422. void addrect(int x, int y, int w, int h);
  423. void newclown(void);
  424. void playsound(int snd);
  425. void resetballoons(int player, int row);
  426. void drawballoon(int player, int x, int y, int off);
  427. void update_background(int which);
  428. void drawnumber(int x, int y, int v, int img);
  429. void drawtext(int x, int y, char * str);
  430. void drawfuzz(int x, int y, int w, int h);
  431. void seticon(void);
  432. void usage(int ret);
  433. FILE * open_option_file(char * mode);
  434. void addscore(int player, int inc);
  435. int highscorescreen(void);
  436. int pausescreen(void);
  437. void getinitials(void);
  438.  
  439.  
  440. /* Global variables: */
  441.  
  442. int use_sound, use_fullscreen, use_low, use_joystick, use_joy_analog,
  443.   num_rects, num_players, coop, barriers, bouncy, clearall, sfx_vol, music_vol,
  444.   has_highscore, highscore_index, show_highscores, highscore_effect;
  445. SDL_Surface * screen;
  446. SDL_Surface * images[NUM_IMAGES];
  447. SDL_Rect rects[MAX_RECTS];
  448. #ifdef JOY_YES
  449. SDL_Joystick * js;
  450. #endif
  451. int flying_active, flying_splat, flying_dir,
  452.   flying_x, flying_y, flying_xm, flying_ym,
  453.   flying_left_arm, flying_right_arm, flying_left_leg, flying_right_leg;
  454. Uint8 balloons[2][NUM_ROWS][20];
  455. int balloon_colors[2][NUM_ROWS];
  456. int score[2], lives[2];
  457. int highscore[8];
  458. char highscorer[8][4];
  459. char username_initials[3];
  460.  
  461.  
  462. #ifndef NOSOUND
  463. Mix_Chunk * sounds[NUM_SOUNDS];
  464. Mix_Music * mus_title, * mus_game, * mus_gameover, * mus_hiscore,
  465.   * mus_hiscreen;
  466. #endif
  467.  
  468.  
  469. /* --- MAIN --- */
  470.  
  471. int main(int argc, char * argv[])
  472. {
  473.   int done, i;
  474.   FILE * fi;
  475.   char temp[512];
  476.  
  477.   
  478.   /* Set program defaults: */
  479.   
  480.   use_sound = 1;
  481.   use_joystick = 1;
  482.   use_joy_analog = 1;
  483.   use_fullscreen = 0;
  484.   use_low = 0;
  485.  
  486.  
  487.   /* Check for arguments: */
  488.   
  489.   for (i = 1; i < argc; i++)
  490.     {
  491.       if (strcmp(argv[i], "--fullscreen") == 0 ||
  492.       strcmp(argv[i], "-f") == 0)
  493.     use_fullscreen = 1;
  494.       else if (strcmp(argv[i], "--digital") == 0 ||
  495.       strcmp(argv[i], "-d") == 0)
  496.     use_joy_analog = 0;
  497.       else if (strcmp(argv[i], "--low") == 0 ||
  498.            strcmp(argv[i], "-l") == 0)
  499.     use_low = 1;
  500.       else if (strcmp(argv[i], "--disable-sound") == 0 ||
  501.            strcmp(argv[i], "--nosound") == 0 ||
  502.            strcmp(argv[i], "-q") == 0)
  503.     use_sound = 0;
  504.       else if (strcmp(argv[i], "--help") == 0 ||
  505.            strcmp(argv[i], "-h") == 0)
  506.     {
  507.       printf("\nCircus Linux!\n"
  508.                  "\n"
  509.          "Version " VERSION "\n"
  510.          "New Breed Software, 2000\n"
  511.                  "\n"
  512.          "Programming: Bill Kendrick\n"
  513.          "Graphics: Manu Parssinen and Bill Kendrick\n"
  514.          "Music: Jarkko Rotsten\n"
  515.          "\n"
  516.          "Game controls:\n"
  517.          "  Mouse Movement   - Move teeter-totter\n"
  518.          "  Any Mouse Button - Launch new clown /\n"
  519.          "                     Flip teeter-totter\n"
  520.          "\n"
  521.          "Run with \"--usage\" for command-line options...\n"
  522.          "Run with \"--copying\" for copying information...\n"
  523.          "\n");
  524.       
  525.       exit(0);
  526.     }
  527.       else if (strcmp(argv[i], "--copying") == 0 ||
  528.            strcmp(argv[i], "-c") == 0)
  529.     {
  530.       printf("\nCircus Linux! is free software; you can redistrubut it\n"
  531.          "and/or modify it under the terms of the GNU General Public\n"
  532.                  "License as published by the Free Software Foundation;\n"
  533.                  "either version 2 of the License, or (at your option) any\n"
  534.                  "later version.\n"
  535.                  "\n"
  536.                  "This program is distributed in the hope that it will be\n"
  537.                  "useful and entertaning, but WITHOUT ANY WARRANTY; without\n"
  538.                  "even the implied warranty of MERCHANTABILITY or FITNESS\n"
  539.                  "FOR A PARTICULAR PURPOSE.  See the GNU General Public\n"
  540.                  "License for more details.\n"
  541.                  "\n"
  542.                  "You should have received a copy of the GNU General Public\n"
  543.                  "License along with this program; if not, write to the Free\n"
  544.                  "Software Foundation, Inc., 59 Temple Place, Suite 330,\n"
  545.                  "Boston, MA  02111-1307  USA\n"
  546.                  "\n");
  547.       
  548.       exit(0);
  549.     }
  550.       else if (strcmp(argv[i], "--version") == 0 ||
  551.            strcmp(argv[i], "-v") == 0)
  552.     {
  553.       printf("Circus Linux! version " VERSION "\n");
  554.       
  555.       exit(0);
  556.     }
  557.       else if (strcmp(argv[i], "--usage") == 0 ||
  558.            strcmp(argv[i], "-u") == 0)
  559.     usage(0);
  560.       else
  561.     usage(1);
  562.     }
  563.   
  564.   
  565.   /* Set option defaults: */
  566.   
  567.   sfx_vol = 3;
  568.   music_vol = 3;
  569.   
  570.   for (i = 0; i < 8; i++)
  571.     {
  572.       highscore[i] = 100;
  573.       strcpy(highscorer[i], "TUX");
  574.     }
  575.   
  576.   
  577.   /* Load options: */
  578.   
  579.   fi = open_option_file("r");
  580.   
  581.   if (fi != NULL)
  582.     {
  583.       do
  584.     {
  585.       fgets(temp, sizeof(temp), fi);
  586.       
  587.       if (!feof(fi))
  588.         {
  589.           temp[strlen(temp) - 1] = '\0';
  590.           
  591.           
  592.           /* Parse each line: */
  593.           
  594.           if (strstr(temp, "highscore") == temp &&
  595.           temp[9] >= '0' && temp[9] <= '7' &&
  596.           temp[10] == '=')
  597.         {
  598.           highscore[temp[9] - '0'] = atoi(temp + 11);
  599.         }
  600.           else if (strstr(temp, "highscorer") == temp &&
  601.           temp[10] >= '0' && temp[10] <= '7' &&
  602.           temp[11] == '=')
  603.         {
  604.           highscorer[temp[10] - '0'][0] = temp[12];
  605.           highscorer[temp[10] - '0'][1] = temp[13];
  606.           highscorer[temp[10] - '0'][2] = temp[14];
  607.         }
  608.           else if (strstr(temp, "effects=") == temp)
  609.         {
  610.           sfx_vol = atoi(temp + 8);
  611.           if (sfx_vol > 3 || sfx_vol < 0)
  612.             sfx_vol = 3;
  613.         }
  614.           else if (strstr(temp, "music=") == temp)
  615.         {
  616.           music_vol = atoi(temp + 6);
  617.           if (music_vol > 3 || music_vol < 0)
  618.             music_vol = 3;
  619.         }
  620.         }
  621.     }
  622.       while (!feof(fi));
  623.       
  624.       fclose(fi);
  625.     }
  626.   
  627.   
  628.   /* Setup: */
  629.   
  630.   setup();
  631.   getinitials();
  632.   
  633.   
  634.   /* Set gameplay defaults: */
  635.  
  636.   num_players = 1;
  637.   coop = 0;
  638.   barriers = 0;
  639.   bouncy = 0;
  640.   clearall = 0;
  641.   
  642.   
  643.   /* --- MAIN FUNCTION LOOP: --- */
  644.   
  645.   done = 0;
  646.   intro();
  647.   
  648.   do
  649.     {
  650.       show_highscores = 0;
  651.       done = title();
  652.       
  653.       if (!done)
  654.     {
  655.       if (show_highscores == 0)
  656.         done = game();
  657.       else
  658.         done = highscorescreen();
  659.     }
  660.     }
  661.   while (!done);
  662.   
  663.   
  664.   /* Save options: */
  665.   
  666.   fi = open_option_file("w");
  667.   if (fi != NULL)
  668.     {
  669.       /* Comment at the top (I wish _everyone_ did this!) */
  670.       
  671.       fprintf(fi, "# Circus Linux! options file\n\n");
  672.       
  673.       
  674.       /* High scores: */
  675.       
  676.       fprintf(fi, "# Highscores:\n\n");
  677.       
  678.       for (i = 0; i < 8; i++)
  679.     {
  680.       fprintf(fi, "highscore%d=%d\n", i, highscore[i]);
  681.       fprintf(fi, "highscorer%d=%s\n\n", i, highscorer[i]);
  682.     }
  683.       
  684.       fprintf(fi, "\n");
  685.       
  686.       
  687.       /* Volume settings: */
  688.       
  689.       fprintf(fi,
  690.           "# Set \"effects\" and \"music\" to a value between 0 and 3.\n"
  691.           "# Where \"0\" is silent and \"3\" is maximum volume (loud).\n"
  692.           "# Where \"effects\" sets sound effects volumes, and\n"
  693.           "# where \"music\" sets music volume.\n\n"
  694.           "# (Default: 3 for both)\n\n");
  695.       
  696.       fprintf(fi, "effects=%d\n", sfx_vol);
  697.       fprintf(fi, "music=%d\n\n\n", music_vol);
  698.       
  699.       
  700.       /* The end! */
  701.       
  702.       fprintf(fi, "# (File automatically created.)\n");
  703.       
  704.       fclose(fi);
  705.     }
  706.   
  707.   
  708.   /* Quit and exit: */
  709.   
  710.   SDL_Quit();
  711.   
  712.   return(0);
  713. }
  714.  
  715.  
  716. /* Game: */
  717.  
  718. int game(void)
  719. {
  720.   int i, x, y, done, quit, frame, any, some, player, background_frame,
  721.     teeter_x, teeter_xm, teeter_xmm, old_teeter_x, teeter_roll,
  722.     teeter_side, teeter_sound, fire,
  723.     show_player, mouse_x, mouse_y, len, act, act_x, act_y, act_xm, act_ym;
  724.   int bouncers[2], barrier_x[3];
  725.   SDL_Event event;
  726.   Uint32 last_time, now_time;
  727.   SDLKey key;
  728.   SDL_Rect dest;
  729.   Uint8 * keystate;
  730.   Sint16 axis;
  731.   
  732.   
  733.   /* Hide mouse pointer: */
  734.   
  735.   SDL_ShowCursor(0);
  736.   
  737.   
  738.   /* Init: */
  739.   
  740.   key = SDLK_UNKNOWN;
  741.   
  742.   frame = 0;
  743.   
  744.   has_highscore = -1;
  745.   highscore_effect = 0;
  746.   
  747.   teeter_side = LEFT;
  748.   teeter_x = 0;
  749.   teeter_xm = 0;
  750.   teeter_xmm = 0;
  751.   teeter_roll = 0;
  752.   teeter_sound = 0;
  753.   mouse_x = 0;
  754.   mouse_y = 0;
  755.   
  756.   bouncers[0] = 0;
  757.   bouncers[1] = 0;
  758.   
  759.   for (player = 0; player < 2; player++)
  760.     {
  761.       lives[player] = STARTING_LIVES;
  762.       score[player] = 0;
  763.       
  764.       for (y = 0; y < NUM_ROWS; y++)
  765.     resetballoons(player, y);
  766.       
  767.       for (y = 0; y < NUM_ROWS; y++)
  768.     balloon_colors[player][y] = y * 2;
  769.     }
  770.   
  771.   act = (rand() % NUM_ACTS);
  772.   player = 0;
  773.   flying_active = 0;
  774.   flying_splat = 0;
  775.   show_player = SHOW_PLAYER_TIME;
  776.   background_frame = 0;
  777.   highscore_index = (barriers * 4 + bouncy * 2 + clearall);
  778.   
  779.   act_x = 0;
  780.   act_y = 0;
  781.   act_xm = 0;
  782.   act_ym = 0;
  783.   
  784.   for (i = 0; i < NUM_BARRIERS; i++)
  785.     barrier_x[i] = i * 128;
  786.   
  787.   done = 0;
  788.   quit = 0;
  789.   
  790.   
  791.   /* Draw entire background: */
  792.   
  793.   if (use_low == 0)
  794.     SDL_BlitSurface(images[IMG_BACKGROUND_0], NULL, screen, NULL);
  795.   else
  796.     SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 50, 50, 80));
  797.   
  798.   SDL_Flip(screen);
  799.   
  800.   
  801.   /* --- MAIN GAME LOOP --- */
  802.   
  803.   do
  804.     {
  805.       last_time = SDL_GetTicks();
  806.       frame++;
  807.       
  808.       
  809.       /* Clear rectangles: */
  810.       
  811.       if (use_low == 0 || !(frame % 2))
  812.     clearrects();
  813.       
  814.       
  815.       /* Animate background: */
  816.       
  817.       if ((frame % 5) == 0 && use_low == 0)
  818.     {
  819.       background_frame = (background_frame + 1) % 2;
  820.       update_background(background_frame);
  821.     }
  822.       
  823.       
  824.       /* Erase teeter-totter: */
  825.       
  826.       erase(teeter_x, 444, 96, 36, IMG_BACKGROUND_0 + background_frame);
  827.       addrect(teeter_x, 444, 96, 36);
  828.       
  829.       
  830.       /* Erase flying clown: */
  831.       
  832.       if (flying_active || flying_splat)
  833.     {
  834.       erase(flying_x, flying_y, 32, 32,
  835.         IMG_BACKGROUND_0 + background_frame);
  836.       addrect(flying_x, flying_y, 32, 32);
  837.     }
  838.       
  839.       
  840.       /* Erase bouncers: */
  841.       
  842.       for (i = 0; i < 2; i++)
  843.     {
  844.       erase(608 * i, 448, 32, 32, IMG_BACKGROUND_0 + background_frame);
  845.       addrect(608 * i, 448, 32, 32);
  846.     }
  847.  
  848.       
  849.       /* Erase act: */
  850.       
  851.       erase(152, 347, 48, 48, IMG_BACKGROUND_0 + background_frame);
  852.       addrect(152, 347, 48, 48);
  853.       
  854.       
  855.       /* Erase balloons: */
  856.       
  857.       for (y = 0; y < NUM_ROWS; y++)
  858.     erase(0, (y * 32) + 32, 640, 32, IMG_BACKGROUND_0 + background_frame);
  859.       
  860.       addrect(0, 32, 640, NUM_ROWS * 32);
  861.       
  862.       
  863.       /* Erase barriers: */
  864.       
  865.       if (barriers)
  866.     {
  867.       erase(0, (NUM_ROWS * 32) + 32, 640, 32,
  868.         IMG_BACKGROUND_0 + background_frame);
  869.     }
  870.       
  871.       
  872.       /* Erase lives status: */
  873.       
  874.       erase(512, 0, 128, 32, IMG_BACKGROUND_0 + background_frame);
  875.       addrect(512, 0, 128, 32);
  876.  
  877.  
  878.       /* Erase score status: */
  879.       
  880.       erase(0, 0, 192, 32, IMG_BACKGROUND_0 + background_frame);
  881.       addrect(0, 0, 192, 32);
  882.       
  883.       
  884.       /* Keep track of old teeter-totter position: */
  885.       
  886.       old_teeter_x = teeter_x;
  887.       
  888.       
  889.       /* Move teeter totter (digital joystick code) */
  890.       
  891.       teeter_x = teeter_x + teeter_xm;
  892.       teeter_xm = teeter_xm + teeter_xmm;
  893.       
  894.       if (teeter_xm > 32)
  895.     teeter_xm = 32;
  896.       else if (teeter_xm < -32)
  897.     teeter_xm = -32;
  898.       
  899.       if (teeter_x < 32)
  900.     teeter_x = 32;
  901.       else if (teeter_x > 512)
  902.     teeter_x = 512;
  903.       
  904.       
  905.       /* Handle events: */
  906.       
  907.       fire = 0;
  908.       
  909.       while (SDL_PollEvent(&event) > 0)
  910.     {
  911.       /* Handle digital controls: */
  912.       
  913.       keystate = SDL_GetKeyState(NULL);
  914.       
  915.       axis = 0;
  916. #ifdef JOY_YES
  917.       if (!use_joy_analog)
  918.         axis = SDL_JoystickGetAxis(js, 0);
  919. #endif
  920.       
  921.       if (keystate[SDLK_LEFT] || axis < -256)
  922.         {
  923.           teeter_xmm = -2;
  924.           if (teeter_xm > 0)
  925.         teeter_xm = 0;
  926.         }
  927.       else if (keystate[SDLK_RIGHT] || axis > 256)
  928.         {
  929.           teeter_xmm = 2;
  930.           if (teeter_xm < 0)
  931.         teeter_xm = 0;
  932.         }
  933.       else
  934.         {
  935.           teeter_xmm = 0;
  936.           teeter_xm = 0;
  937.         }
  938.       
  939.       
  940.       /* Handle incoming events: */
  941.       
  942.       if (event.type == SDL_QUIT)
  943.         {
  944.           /* Quit request: */
  945.           
  946.           quit = 1;
  947.         }
  948.           else if (event.type == SDL_KEYDOWN)
  949.             {
  950.               /* A keypress! */
  951.               
  952.               key = event.key.keysym.sym;
  953.               
  954.               if (key == SDLK_ESCAPE)
  955.                 {
  956.                   /* Escape: Quit the game and return to main menu: */
  957.                   
  958.                   done = 1;
  959.                 }
  960.           else if (key == SDLK_SPACE || key == SDLK_TAB ||
  961.                key == SDLK_p)
  962.         {
  963.           /* SPACE, TAB or P: Pause! */
  964.           
  965.           done = pausescreen();
  966.           if (done == 2)
  967.             {
  968.               done = 0;
  969.               quit = 1;
  970.             }
  971.         }
  972.           else if (key == SDLK_LALT || key == SDLK_RALT ||
  973.                key == SDLK_LSHIFT || key == SDLK_RSHIFT ||
  974.                key == SDLK_RETURN)
  975.         {
  976.           /* Fire button! */
  977.           
  978.           fire = 1;
  979.         }
  980.         }
  981.       else if (event.type == SDL_MOUSEMOTION)
  982.         {
  983.           teeter_x = event.motion.x - 48;
  984.           mouse_x = event.motion.x;
  985.           mouse_y = event.motion.y;
  986.           
  987.           if (teeter_x < 32)
  988.         teeter_x = 32;
  989.           else if (teeter_x > 512)
  990.         teeter_x = 512;
  991.         }
  992. #ifdef JOY_YES
  993.       else if (event.type == SDL_JOYAXISMOTION)
  994.         {
  995.           /* Joystick motion: */
  996.           
  997.           if (use_joy_analog)
  998.         {
  999.           /* Analog: */
  1000.           
  1001.           if (event.jaxis.axis == 0)
  1002.             {
  1003.               teeter_x = ((event.jaxis.value + 32768) / 68) - 48;
  1004.               
  1005.               if (teeter_x < 32)
  1006.             teeter_x = 32;
  1007.               else if (teeter_x > 512)
  1008.             teeter_x = 512;
  1009.             }
  1010.         }
  1011.         }
  1012. #endif
  1013.       else if (event.type == SDL_MOUSEBUTTONDOWN
  1014. #ifdef JOY_YES
  1015.            || event.type == SDL_JOYBUTTONDOWN
  1016. #endif
  1017.            )
  1018.         {
  1019.           fire = 1;
  1020.         }
  1021.     }
  1022.  
  1023.       
  1024.       /* Handle fire button: */
  1025.       
  1026.       if (fire)
  1027.     {
  1028.       /* Swap teeter-totter side: */
  1029.       
  1030.       if (flying_active)
  1031.         teeter_side = 1 - teeter_side;
  1032.       
  1033.       
  1034.       /* Activate a new clown: */
  1035.       
  1036.       if (flying_active == 0 && flying_splat == 0)
  1037.         {
  1038.           /* Add the new clown: */
  1039.           
  1040.           newclown();
  1041.           
  1042.           
  1043.           /* Erase "Player X Ready" message, if any: */
  1044.           
  1045.           if (show_player > 0)
  1046.         show_player = 1;
  1047.         }
  1048.     }
  1049.       
  1050.       
  1051.       /* Handle highscore effect: */
  1052.       
  1053.       if (highscore_effect > 0)
  1054.     highscore_effect--;
  1055.  
  1056.  
  1057.       /* Handle the barrel: */
  1058.       
  1059.       if (teeter_x > old_teeter_x)
  1060.     {
  1061.       teeter_roll = teeter_roll + 1;
  1062.       if (teeter_roll > 3)
  1063.         teeter_roll = 0;
  1064.     }
  1065.       else if (teeter_x < old_teeter_x)
  1066.     {
  1067.       teeter_roll = teeter_roll - 1;
  1068.       if (teeter_roll < 0)
  1069.         teeter_roll = 3;
  1070.     }
  1071.       
  1072.       
  1073.       /* Handle bouncers: */
  1074.       
  1075.       for (i = 0; i < 2; i++)
  1076.     {
  1077.       if (bouncers[i] > 0)
  1078.         bouncers[i]--;
  1079.     }
  1080.       
  1081.       
  1082.       /* Handle barriers: */
  1083.       
  1084.       if (barriers)
  1085.     {
  1086.       for (i = 0; i < NUM_BARRIERS; i++)
  1087.         {
  1088.           /* Move and wrap-around: */
  1089.           
  1090.           barrier_x[i] = barrier_x[i] + 8;
  1091.           
  1092.           if (barrier_x[i] >= 640)
  1093.         barrier_x[i] = -64;
  1094.         }
  1095.     }
  1096.       
  1097.       
  1098.       /* Handle balloons: */
  1099.       
  1100.       any = 0;
  1101.       
  1102.       for (y = 0; y < NUM_ROWS; y++)
  1103.     {
  1104.       /* Handle popping: */
  1105.       
  1106.       some = 0;
  1107.       
  1108.       for (x = 0; x < 20; x++)
  1109.         {
  1110.           if (balloons[player][y][x] == POPPING0)
  1111.         balloons[player][y][x] = GONE;
  1112.           else if (balloons[player][y][x] > POPPING0)
  1113.         balloons[player][y][x]--;
  1114.           
  1115.           if (balloons[player][y][x] == NORMAL)
  1116.         {
  1117.           some = 1;
  1118.           any = 1;
  1119.         }
  1120.         }
  1121.       
  1122.       
  1123.       /* All balloons popped?  Add more? */
  1124.       
  1125.       if (some == 0 && flying_y > (NUM_ROWS * 32) + 64 &&
  1126.           clearall == 0)
  1127.         {
  1128.           resetballoons(player, y);
  1129.           balloon_colors[player][y]++;
  1130.           
  1131.           if (balloon_colors[player][y] > 7)
  1132.         balloon_colors[player][y] = 0;
  1133.           
  1134.           if (y == 0)
  1135.         {
  1136.           addscore(player, 1000);
  1137.           lives[player]++;
  1138.           playsound(SND_CHEERING);
  1139.         }
  1140.           else if (y == 1)
  1141.         {
  1142.           addscore(player, 250);
  1143.           playsound(SND_APPLAUSE);
  1144.         }
  1145.           else if (y == 2)
  1146.         {
  1147.           addscore(player, 100);
  1148.           playsound(SND_APPLAUSE);
  1149.         }
  1150.         }
  1151.       
  1152.       
  1153.       /* Move balloons: */
  1154.       
  1155.       if ((frame % 4) == 0)
  1156.         {
  1157.           if ((y % 2) == 0)
  1158.         {
  1159.           /* Left: */
  1160.           
  1161.           i = balloons[player][y][0];
  1162.           
  1163.           for (x = 0; x < 19; x++)
  1164.             balloons[player][y][x] = balloons[player][y][x + 1];
  1165.           
  1166.           balloons[player][y][19] = i;
  1167.         }
  1168.           else
  1169.         {
  1170.           /* Right: */
  1171.           
  1172.           i = balloons[player][y][19];
  1173.           
  1174.           for (x = 18; x >= 0; x--)
  1175.             balloons[player][y][x + 1] = balloons[player][y][x];
  1176.           
  1177.           balloons[player][y][0] = i;
  1178.         }
  1179.         }
  1180.     }
  1181.  
  1182.  
  1183.       /* Reset all balloons? */
  1184.       
  1185.       if (clearall && !any && flying_y > (NUM_ROWS * 32) + 64)
  1186.     {
  1187.       for (y = 0; y < 3; y++)
  1188.         {
  1189.           resetballoons(player, y);
  1190.           balloon_colors[player][y]++;
  1191.           
  1192.           if (balloon_colors[player][y] > 7)
  1193.         balloon_colors[player][y] = 0;
  1194.           
  1195.           if (y == 0)
  1196.         {
  1197.           addscore(player, 1000);
  1198.           lives[player]++;
  1199.           playsound(SND_CHEERING);
  1200.         }
  1201.           else if (y == 1)
  1202.         {
  1203.           addscore(player, 250);
  1204.           playsound(SND_APPLAUSE);
  1205.         }
  1206.           else if (y == 2)
  1207.         {
  1208.           addscore(player, 100);
  1209.           playsound(SND_APPLAUSE);
  1210.         }
  1211.         }
  1212.     }
  1213.       
  1214.       
  1215.       /* Handle flying clown: */
  1216.       
  1217.       if (flying_active)
  1218.     {
  1219.       /* Move the clown: */
  1220.       
  1221.       flying_x = flying_x + flying_xm;
  1222.       flying_y = flying_y + flying_ym;
  1223.       
  1224.       
  1225.       /* Bounce off top: */
  1226.       
  1227.       if (flying_y < 32)
  1228.         {
  1229.           flying_y = 32;
  1230.           flying_ym = 0;
  1231.         }
  1232.       
  1233.       
  1234.       /* Bounce off bouncers: */
  1235.       
  1236.       if (flying_y > 416 && (flying_x < 32 || flying_x > 576))
  1237.         {
  1238.           flying_y = 416;
  1239.           flying_ym = -abs(flying_ym);
  1240.           
  1241.           
  1242.           /* Make bouncer squish and launch clown towards center: */
  1243.           
  1244.           if (flying_x < 32)
  1245.         {
  1246.           bouncers[0] = BOUNCER_TIME;
  1247.           flying_xm = 8;
  1248.         }
  1249.           else
  1250.         {
  1251.           bouncers[1] = BOUNCER_TIME;
  1252.           flying_xm = -8;
  1253.         }
  1254.           
  1255.           
  1256.           /* Give a point for bouncing: */
  1257.           
  1258.           addscore(player, 1);
  1259.           
  1260.           
  1261.           /* Play bouncer sound: */
  1262.           
  1263.           playsound(SND_BOUNCE);
  1264.         }
  1265.       
  1266.       
  1267.       /* Bounce off barriers: */
  1268.       
  1269.       if (barriers)
  1270.         {
  1271.           for (i = 0; i < NUM_BARRIERS; i++)
  1272.         {
  1273.           if (flying_y >= (NUM_ROWS * 32) &&
  1274.               flying_y <= (NUM_ROWS * 32) + 64 &&
  1275.               flying_x >= barrier_x[i] - 32 &&
  1276.               flying_x <= barrier_x[i] + 64)
  1277.             {
  1278.               if (flying_y <= (NUM_ROWS * 32) + 32)
  1279.             {
  1280.               flying_y = NUM_ROWS * 32;
  1281.               flying_ym = -abs(flying_ym);
  1282.             }
  1283.               else
  1284.             {
  1285.               flying_y = (NUM_ROWS * 32) + 64;
  1286.               flying_ym = abs(flying_ym);
  1287.             }
  1288.               
  1289.               playsound(SND_BOUNCE);
  1290.             }
  1291.         }
  1292.         }
  1293.       
  1294.       
  1295.       /* Bounce off teeter-totter or splat: */
  1296.       
  1297.       if (flying_y > 448)
  1298.         {
  1299.           flying_y = 448;
  1300.           
  1301.           
  1302.           /* Did we hit the teeter-totter? */
  1303.           
  1304.           if ((teeter_side == RIGHT &&
  1305.            (flying_x >= teeter_x && flying_x <= teeter_x + 96)) ||
  1306.           (teeter_side == LEFT &&
  1307.            (flying_x >= teeter_x - 32 && flying_x <= teeter_x + 64)))
  1308.         {
  1309.           /* Yes!  Bounce other the clown: */
  1310.           
  1311.           flying_ym = -(abs(flying_x - (teeter_x + 48 - 16)) / 3) - 16;
  1312.           flying_y = 432;
  1313.           
  1314.           
  1315.           if (teeter_side == LEFT)
  1316.             {
  1317.               flying_x = teeter_x + 64;
  1318.               flying_dir = LEFT;
  1319.               teeter_side = RIGHT;
  1320.             }
  1321.           else
  1322.             {
  1323.               flying_x = teeter_x;
  1324.               flying_dir = RIGHT;
  1325.               teeter_side = LEFT;
  1326.             }
  1327.           
  1328.           
  1329.           /* Randomly pick a X direction: */
  1330.           
  1331.           if ((rand() % 2) == 0)
  1332.             {
  1333.               if (flying_xm != 0)
  1334.             flying_xm = 0;
  1335.               else
  1336.             flying_xm = -4;
  1337.             }
  1338.           
  1339.           
  1340.           /* Randomly change X direction (sign): */
  1341.           
  1342.           if ((rand() % 2) == 0)
  1343.             {
  1344.               flying_xm = -flying_xm;
  1345.             }
  1346.           
  1347.           
  1348.           /* Give a point for bouncing: */
  1349.           
  1350.           addscore(player, 1);
  1351.           
  1352.           
  1353.           /* Play teeter-totter bounce sound: */
  1354.           
  1355.           playsound(SND_TEETER1 + teeter_sound);
  1356.           teeter_sound = !teeter_sound;
  1357.         }
  1358.           else
  1359.         {
  1360.           /* No!  Splat the flying clown! */
  1361.           
  1362.           flying_active = 0;
  1363.           flying_splat = FLYING_SPLAT_TIME;
  1364.           lives[player]--;
  1365.           playsound(SND_SPLAT);
  1366.         }
  1367.         }
  1368.       
  1369.       
  1370.       /* Bounce off balloons: */
  1371.       
  1372.       x = (flying_x + 16) / 32;
  1373.       y = (flying_y / 32) - 1;
  1374.  
  1375.       if ((frame / 2) % 2)
  1376.         {
  1377.           if ((y % 2) == 0)
  1378.         x = (flying_x / 32);
  1379.           else
  1380.         x = (flying_x / 32) + 1;
  1381.         }
  1382.       
  1383.       
  1384.       if (y >= 0 && y < NUM_ROWS)
  1385.         {
  1386.           if (balloons[player][y][x] == NORMAL)
  1387.         {
  1388.           balloons[player][y][x] = POPPING1;
  1389.           playsound(SND_POP);
  1390.           
  1391.           
  1392.           addscore(player, y + 1);
  1393.           
  1394.           
  1395.           /* Bounce horizontally: */
  1396.           
  1397.           if ((flying_x % 32) < 16)
  1398.             flying_xm = -4;
  1399.           else
  1400.             flying_xm = 4;
  1401.           
  1402.           
  1403.           /* Bounce vertically: */
  1404.           
  1405.           if (bouncy == 1)
  1406.             {
  1407.               flying_ym = -flying_ym;
  1408.               
  1409.               if (flying_ym > FASTEST_YM_OFF_BALLOON)
  1410.             flying_ym = FASTEST_YM_OFF_BALLOON;
  1411.             }
  1412.         }
  1413.         }
  1414.       
  1415.       
  1416.       /* Bounce off sides: */
  1417.       
  1418.       if (flying_x < 0)
  1419.         {
  1420.           flying_x = 0;
  1421.           flying_xm = abs(flying_xm);
  1422.         }
  1423.       else if (flying_x > 608)
  1424.         {
  1425.           flying_x = 608;
  1426.           flying_xm = -abs(flying_xm);
  1427.         }
  1428.       
  1429.       
  1430.       /* Deal with gravity: */
  1431.       
  1432.       flying_ym = flying_ym + GRAVITY;
  1433.       
  1434.       if (flying_ym > MAX_YM)
  1435.         flying_ym = MAX_YM;
  1436.       if (flying_ym < -MAX_YM)
  1437.         flying_ym = -MAX_YM;
  1438.     }
  1439.       
  1440.       
  1441.       /* Count splats down: */
  1442.       
  1443.       if (flying_splat)
  1444.     {
  1445.       flying_splat--;
  1446.       
  1447.       
  1448.       /* If out of clowns, show game over while clown is splat: */
  1449.       
  1450.       if (lives[player] == 0)
  1451.         {
  1452.           if (num_players == 1)
  1453.         {
  1454.           drawfuzz(176, 224, 288, 32);
  1455.           drawtext(176, 224, "GAME OVER");
  1456.         }
  1457.           else if (num_players == 2)
  1458.         {
  1459.           drawfuzz(176, 192, 288, 96);
  1460.           drawtext(224, 192, "PLAYER");
  1461.           drawnumber(304, 224, player + 1, IMG_NUMBERS_0 + player);
  1462.           drawtext(176, 256, "GAME OVER");
  1463.         }
  1464.         }
  1465.       
  1466.       
  1467.       if (flying_splat == 0)
  1468.         {
  1469.           /* Switch players: */
  1470.           
  1471.           if (num_players == 2)
  1472.         {
  1473.           /* Copy balloons if in coop mode: */
  1474.           
  1475.           if (coop)
  1476.             {
  1477.               for (y = 0; y < NUM_ROWS; y++)
  1478.             {
  1479.               for (x = 0; x < 20; x++)
  1480.                 {
  1481.                   balloons[1 - player][y][x] =
  1482.                 balloons[player][y][x];
  1483.                 }
  1484.             }
  1485.             }
  1486.           
  1487.           
  1488.           /* Swap player: */
  1489.           
  1490.           player = 1 - player;
  1491.           
  1492.           if (lives[player] == 0)
  1493.             {
  1494.               player = 1 - player;
  1495.               erase(0, 0, 640, 480,
  1496.                 IMG_BACKGROUND_0 + background_frame);
  1497.               SDL_Flip(screen);
  1498.             }
  1499.         }
  1500.           
  1501.           
  1502.           /* Erase "Game over" display: */
  1503.           
  1504.           if (num_players == 1)
  1505.         erase(176, 224, 288, 32, IMG_BACKGROUND_0 + background_frame);
  1506.           else
  1507.         erase(176, 192, 288, 96, IMG_BACKGROUND_0 + background_frame);
  1508.  
  1509.           
  1510.           /* Show which player is playing now: */
  1511.  
  1512.           show_player = SHOW_PLAYER_TIME;
  1513.  
  1514.  
  1515.           /* No more lives? */
  1516.           
  1517.           if (lives[player] == 0)
  1518.         {
  1519.           done = 1;
  1520.         }
  1521.         }
  1522.     }
  1523.       
  1524.       
  1525.       /* Change limb positions: */
  1526.       
  1527.       if (flying_active || flying_splat)
  1528.     {
  1529.       if ((frame % LIMB_ANIMATION_TIME) == 0)
  1530.         {
  1531.           flying_left_arm = rand() % 3;
  1532.           flying_right_arm = rand() % 3;
  1533.           flying_left_leg = rand() % 2;
  1534.           flying_right_leg = rand() % 2;
  1535.         }
  1536.     }
  1537.       
  1538.       
  1539.       /* Draw act: */
  1540.       
  1541.       if (!use_low)
  1542.     {
  1543.       if (act == ACT_SEAL)
  1544.         {
  1545.           erase(148, act_y, 32, 32, IMG_BACKGROUND_0 + background_frame);
  1546.           addrect(148, act_y, 32, 32);
  1547.           
  1548.           act_y = act_y + act_ym;
  1549.           act_ym++;
  1550.           
  1551.           if (act_y >= 315)
  1552.         {
  1553.           act_y = 315;
  1554.           act_ym = -10;
  1555.         }
  1556.           
  1557.           draw(148, act_y, IMG_BEACHBALL_0 + ((frame / 4) % 3));
  1558.           addrect(148, act_y, 32, 32);
  1559.           
  1560.           draw(152, 347, IMG_SEAL_0 + ((frame / 4) % 2));
  1561.           addrect(152, 315, 48, 48);
  1562.         }
  1563.       else if (act == ACT_BEAR)
  1564.         {
  1565.           erase(act_x, 340, 48, 96, IMG_BACKGROUND_0 + background_frame);
  1566.           addrect(act_x, 340, 48, 96);
  1567.           
  1568.           act_x = act_x + act_xm;
  1569.           if (act_x <= 64)
  1570.         {
  1571.           act_x = 64;
  1572.           act_xm = 4;
  1573.         }
  1574.           else if (act_x >= 524)
  1575.         {
  1576.           act_x = 524;
  1577.           act_xm = -4;
  1578.         }
  1579.           
  1580.           if (act_xm > 0)
  1581.         draw(act_x, 340, IMG_BEAR_RIGHT_0 + ((frame / 4) % 2));
  1582.           else
  1583.         draw(act_x, 340, IMG_BEAR_LEFT_0 + ((frame / 4) % 2));
  1584.           addrect(act_x, 340, 48, 96);
  1585.         }
  1586.     }
  1587.       
  1588.       
  1589.       /* Draw balloons: */
  1590.       
  1591.       for (y = 0; y < NUM_ROWS; y++)
  1592.     {
  1593.       for (x = 0; x < 20; x++)
  1594.         {
  1595.           drawballoon(player, x, y, ((frame / 2) % 2));
  1596.         }
  1597.     }
  1598.       
  1599.       addrect(0, 32, 640, NUM_ROWS * 32);
  1600.       
  1601.       
  1602.       /* Draw barriers: */
  1603.       
  1604.       if (barriers)
  1605.     {
  1606.       for (i = 0; i < 3; i++)
  1607.         draw(barrier_x[i], (NUM_ROWS * 32) + 32, IMG_BARRIER);
  1608.       
  1609.       addrect(0, (NUM_ROWS * 32) + 32, 640, 32);
  1610.     }
  1611.       
  1612.       
  1613.       /* Draw teeter-totter: */
  1614.       
  1615.       if (teeter_side == LEFT)
  1616.     draw(teeter_x, 448, IMG_TEETER_TOTTER_LEFT_0 + teeter_roll);
  1617.       else if (teeter_side == RIGHT)
  1618.     draw(teeter_x, 448, IMG_TEETER_TOTTER_RIGHT_0 + teeter_roll);
  1619.       
  1620.       
  1621.       /* Draw clown on teeter-totter: */
  1622.       
  1623.       drawclown(teeter_x + 64 - (teeter_side * 64), 444, teeter_side,
  1624.         1, 1, 1, 1);
  1625.       
  1626.       addrect(teeter_x, 444, 96, 36);
  1627.       
  1628.       
  1629.       /* Draw flying clown: */
  1630.       
  1631.       if (flying_active)
  1632.     {
  1633.       drawclown(flying_x, flying_y, flying_dir,
  1634.             flying_left_arm, flying_right_arm,
  1635.             flying_left_leg, flying_right_leg);
  1636.       
  1637.       addrect(flying_x, flying_y, 32, 32);
  1638.     }
  1639.  
  1640.  
  1641.       /* Draw splat clown: */
  1642.       
  1643.       if (flying_splat)
  1644.     {
  1645.       drawclown(flying_x, flying_y, 2,
  1646.             -1, -1,
  1647.             flying_left_leg + 2, flying_right_leg + 2);
  1648.       
  1649.       addrect(flying_x, flying_y, 32, 32);
  1650.     }
  1651.       
  1652.       
  1653.       /* Draw bouncers: */
  1654.       
  1655.       for (i = 0; i < 2; i++)
  1656.     {
  1657.       if (bouncers[i] == 0)
  1658.         draw(608 * i, 448, IMG_BOUNCER_0);
  1659.       else
  1660.         draw(608 * i, 448, IMG_BOUNCER_1);
  1661.       
  1662.       addrect(608 * i, 448, 32, 32);
  1663.     }
  1664.       
  1665.       
  1666.       /* Draw lives status: */
  1667.       
  1668.       drawfuzz(512, 0, 128, 32);
  1669.       
  1670.       if (mouse_x < 500 || mouse_x > 556 || mouse_y > 44)
  1671.     {
  1672.       /* Not near head, show normal clown face: */
  1673.       
  1674.       draw(512, 0, IMG_CLOWN_HEAD);
  1675.     }
  1676.       else
  1677.     {
  1678.       /* Near head!  Show excited clown face: */
  1679.       
  1680.       draw(512, 0, IMG_CLOWN_HEAD_OH);
  1681.     }
  1682.       
  1683.       draw(544, 0, IMG_TIMES);
  1684.       addrect(512, 0, 64, 32);
  1685.       
  1686.       drawnumber(576, 0, lives[player], IMG_NUMBERS_0 + player);
  1687.       
  1688.       
  1689.       /* Draw score status: */
  1690.       
  1691.       drawfuzz(0, 0, 192, 32);
  1692.       drawnumber(0, 0, score[player], IMG_NUMBERS_0 + player);
  1693.       
  1694.       
  1695.       /* Draw "Player X Ready" message: */
  1696.       
  1697.       if (show_player > 0 && lives[player] > 0)
  1698.     {
  1699.       if (num_players == 1)
  1700.         {
  1701.           drawfuzz(240, 224, 160, 32);
  1702.           drawtext(240, 224, "READY");
  1703.         }
  1704.       else if (num_players == 2)
  1705.         {
  1706.           drawfuzz(224, 192, 192, 96);
  1707.           drawtext(224, 192, "PLAYER");
  1708.           drawnumber(304, 224, player + 1, IMG_NUMBERS_0 + player);
  1709.           drawtext(240, 256, "READY");
  1710.         }
  1711.  
  1712.       
  1713.       /* Count timer down: */
  1714.       
  1715.       show_player--;
  1716.       
  1717.       
  1718.       /* Erase "Player X Ready" message: */
  1719.       
  1720.       if (show_player == 0)
  1721.         {
  1722.           if (num_players == 1)
  1723.         {
  1724.           erase(240, 224, 160, 32,
  1725.             IMG_BACKGROUND_0 + background_frame);
  1726.           addrect(240, 224, 160, 32);
  1727.         }
  1728.           else if (num_players == 2)
  1729.         {
  1730.           erase(224, 192, 192, 96,
  1731.             IMG_BACKGROUND_0 + background_frame);
  1732.           addrect(224, 192, 192, 96);
  1733.         }
  1734.         }
  1735.     }
  1736.       
  1737.       
  1738.       /* Update the screen: */
  1739.       
  1740.       if (use_low == 0 || (frame % 2))
  1741.     SDL_UpdateRects(screen, num_rects, rects);
  1742.       
  1743.       
  1744.       /* Pause: */
  1745.       
  1746.       now_time = SDL_GetTicks();
  1747.       if (now_time < last_time + FPS)
  1748.     SDL_Delay(last_time + FPS - now_time);
  1749.       
  1750.       
  1751.       /* Keep playing music: */
  1752.       
  1753. #ifndef NOSOUND
  1754.       if (use_sound == 1)
  1755.     {
  1756.       if (!Mix_PlayingMusic())
  1757.         {
  1758.           Mix_PlayMusic(mus_game, 0);
  1759.           Mix_VolumeMusic((music_vol * MIX_MAX_VOLUME) / 3);
  1760.         }
  1761.     }
  1762. #endif
  1763.     }
  1764.   while (done == 0 && quit == 0);
  1765.   
  1766.   
  1767.   /* Stop music and sounds: */
  1768.   
  1769. #ifndef NOSOUND
  1770.   if (use_sound == 1)
  1771.     {
  1772.       Mix_HaltMusic();
  1773.       Mix_HaltChannel(-1);
  1774.     }
  1775. #endif
  1776.   
  1777.  
  1778.   /* Show scores: */
  1779.   
  1780.   if (quit == 0)
  1781.     {
  1782.       /* Darken screen: */
  1783.       
  1784.       drawfuzz(0, 0, 640, 480);
  1785.       SDL_Flip(screen);
  1786.       SDL_Delay(300);
  1787.       
  1788.       
  1789.       /* Blank screen: */
  1790.       
  1791.       SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
  1792.       
  1793.       
  1794.       /* Draw "Final Score(s)" Text: */
  1795.       
  1796.       if (num_players == 1)
  1797.     drawtext(144, 144, "FINAL SCORE");
  1798.       else
  1799.     drawtext(128, 144, "FINAL SCORES");
  1800.       
  1801.       
  1802.       /* Show players' scores: */
  1803.       
  1804.       if (num_players == 1)
  1805.     {
  1806.       drawnumber(224, 272, score[0], IMG_NUMBERS_0);
  1807.       
  1808.       if (has_highscore == 0)
  1809.         {
  1810.           drawtext(208, 0, "HISCORE");
  1811.           draw(207, 64, IMG_ENTER_INITIALS);
  1812.         }
  1813.     }
  1814.       else
  1815.     {
  1816.       /* Show player 1's score: */
  1817.       
  1818.       drawtext(0, 208, "PLAYER");
  1819.       drawtext(208, 208, "ONE");
  1820.       drawnumber(0, 272, score[0], IMG_NUMBERS_0);
  1821.       
  1822.       if (has_highscore == 0)
  1823.         {
  1824.           drawtext(0, 0, "HISCORE");
  1825.           draw(0, 64, IMG_ENTER_INITIALS);
  1826.         }
  1827.       
  1828.       
  1829.       /* Show player 2's score: */
  1830.       
  1831.       drawtext(336, 208, "PLAYER");
  1832.       drawtext(544, 208, "TWO");
  1833.       drawnumber(336, 272, score[1], IMG_NUMBERS_1);
  1834.       
  1835.       if (has_highscore == 1)
  1836.         {
  1837.           drawtext(416, 0, "HISCORE");
  1838.           draw(415, 64, IMG_ENTER_INITIALS);
  1839.         }
  1840.     }
  1841.       
  1842.       
  1843.       /* Did someone get a high score?  Set high score initials to null*/
  1844.       
  1845.       if (has_highscore != -1)
  1846.     strcpy(highscorer[highscore_index], "");
  1847.       len = 0;
  1848.       
  1849.       
  1850.       SDL_Flip(screen);
  1851.       
  1852.       done = 0;
  1853.       
  1854.       
  1855.       /* Wait for something: */
  1856.       
  1857.       do
  1858.     {
  1859.       frame++;
  1860.       
  1861.       while (SDL_PollEvent(&event) > 0)
  1862.         {
  1863.           if (event.type == SDL_QUIT)
  1864.         {
  1865.           /* Quit request: done and quit! */
  1866.           
  1867.           done = 1;
  1868.           quit = 1;
  1869.         }
  1870.           else if (event.type == SDL_KEYDOWN)
  1871.         {
  1872.           /* A keypress! */
  1873.           
  1874.           key = event.key.keysym.sym;
  1875.           
  1876.           if (key == SDLK_ESCAPE)
  1877.             {
  1878.               /* Escape: done: */
  1879.               
  1880.               done = 1;
  1881.             }
  1882.           
  1883.           
  1884.           /* Does someone have high score? Accept input! */
  1885.           
  1886.           if (has_highscore != -1)
  1887.             {
  1888.               if (key >= SDLK_a && key <= SDLK_z && len < 3)
  1889.             {
  1890.               highscorer[highscore_index][len] = ((key - SDLK_a) +
  1891.                                   'A');
  1892.               len++;
  1893.               highscorer[highscore_index][len] = '\0';
  1894.               
  1895.               playsound(SND_KEYPRESS);
  1896.             }
  1897.               else if ((key == SDLK_BACKSPACE ||
  1898.                 key == SDLK_DELETE) &&
  1899.                    len > 0)
  1900.             {
  1901.               len--;
  1902.               highscorer[highscore_index][len] = '\0';
  1903.               playsound(SND_POP);
  1904.             }
  1905.               else if (key == SDLK_RETURN)
  1906.             {
  1907.               done = 1;
  1908.               playsound(SND_HIGHSCORE);
  1909.             }
  1910.               
  1911.               
  1912.               /* Update text: */
  1913.               
  1914.               if (has_highscore == 0)
  1915.             {
  1916.               if (num_players == 1)
  1917.                 {
  1918.                   /* Erase: */
  1919.                   
  1920.                   dest.x = 272;
  1921.                   dest.y = 32;
  1922.                   dest.w = 96;
  1923.                   dest.h = 32;
  1924.                   
  1925.                   SDL_FillRect(screen, &dest,
  1926.                        SDL_MapRGB(screen->format,
  1927.                               0, 0, 0));
  1928.                   
  1929.                   
  1930.                   /* Redraw: */
  1931.                   
  1932.                   drawtext(272, 32, highscorer[highscore_index]);
  1933.                   
  1934.                   
  1935.                   /* Update: */
  1936.                   
  1937.                   SDL_UpdateRect(screen, 272, 32, 96, 32);
  1938.                 }
  1939.               else
  1940.                 {
  1941.                   /* Erase: */
  1942.                   
  1943.                   dest.x = 0;
  1944.                   dest.y = 32;
  1945.                   dest.w = 96;
  1946.                   dest.h = 32;
  1947.                   
  1948.                   SDL_FillRect(screen, &dest,
  1949.                        SDL_MapRGB(screen->format,
  1950.                               0, 0, 0));
  1951.                   
  1952.                   
  1953.                   /* Redraw: */
  1954.                   
  1955.                   drawtext(0, 32, highscorer[highscore_index]);
  1956.                   
  1957.                   
  1958.                   /* Update: */
  1959.                   
  1960.                   SDL_UpdateRect(screen, 0, 32, 96, 32);
  1961.                 }
  1962.             }
  1963.               else
  1964.             {
  1965.               /* Erase: */
  1966.               
  1967.               dest.x = 544;
  1968.               dest.y = 32;
  1969.               dest.w = 96;
  1970.               dest.h = 32;
  1971.               
  1972.               SDL_FillRect(screen, &dest,
  1973.                        SDL_MapRGB(screen->format, 0, 0, 0));
  1974.               
  1975.               
  1976.               /* Redraw: */
  1977.               
  1978.               drawtext(544, 32, highscorer[highscore_index]);
  1979.               
  1980.               
  1981.               /* Update: */
  1982.               
  1983.               SDL_UpdateRect(screen, 544, 32, 96, 32);
  1984.             }
  1985.             }
  1986.         }
  1987.           else if (event.type == SDL_MOUSEBUTTONDOWN &&
  1988.                has_highscore == -1)
  1989.         {
  1990.           /* Click - done: */
  1991.           
  1992.           done = 1;
  1993.         }
  1994.         }
  1995.       
  1996.       
  1997.       /* Draw sad clown: */
  1998.       
  1999.       draw(512, 320, IMG_SADCLOWN_0 + (frame / 5) % 3);
  2000.       SDL_UpdateRect(screen, 512, 320, 128, 160);
  2001.       
  2002.       
  2003.       /* Play game-over or high-score music: */
  2004.       
  2005. #ifndef NOSOUND
  2006.       if (use_sound == 1)
  2007.         {
  2008.           if (!Mix_PlayingMusic())
  2009.         {
  2010.           if (has_highscore == -1)
  2011.             Mix_PlayMusic(mus_gameover, 0);
  2012.           else
  2013.             Mix_PlayMusic(mus_hiscore, 0);
  2014.           
  2015.           Mix_VolumeMusic((music_vol * MIX_MAX_VOLUME) / 3);
  2016.         }
  2017.         }
  2018. #endif
  2019.       
  2020.       
  2021.       /* Pause: */
  2022.       
  2023.       SDL_Delay(30);
  2024.     }
  2025.       while (done == 0);
  2026.  
  2027.       
  2028.       /* Did a name get entered? */
  2029.       
  2030.       if (has_highscore != -1)
  2031.     {
  2032.       if (highscorer[highscore_index][0] == '\0')
  2033.         strcpy(highscorer[highscore_index], username_initials);
  2034.     }
  2035.       
  2036.       /* Silence music: */
  2037.       
  2038. #ifndef NOSOUND
  2039.       if (use_sound == 1)
  2040.     Mix_HaltMusic();
  2041. #endif
  2042.     }
  2043.   
  2044.   
  2045.   /* Back to main!: */
  2046.   
  2047.   return(quit);
  2048. }
  2049.  
  2050.  
  2051. /* Intro screen: */
  2052.  
  2053. void intro(void)
  2054. {
  2055.   int i;
  2056.   
  2057.   for (i = 0; i < 50; i++)
  2058.     {
  2059.       if (i == 5)
  2060.     {
  2061.       drawtext(32, 176, "NEW BREED SOFTWARE");
  2062.       SDL_UpdateRect(screen, 0, 176, 640, 32);
  2063.     }
  2064.       else if (i == 25)
  2065.     {
  2066.       drawtext(192, 288, "PRESENTS");
  2067.       SDL_UpdateRect(screen, 0, 288, 640, 32);
  2068.     }
  2069.       
  2070.       SDL_Delay(30);
  2071.     }
  2072. }
  2073.  
  2074.  
  2075. /* Title screen: */
  2076.  
  2077. int title(void)
  2078. {
  2079.   SDL_Event event;
  2080.   int done, quit, i, j, frame, tmp, text_x, text_xm, text_img, text_time,
  2081.     highlight_x, highlight_y, highlight_w, highlight_h,
  2082.     old_highlight_x, old_highlight_y, old_highlight_w, old_highlight_h;
  2083.   int x[NUM_TITLE_BALLOONS], y[NUM_TITLE_BALLOONS],
  2084.     xm[NUM_TITLE_BALLOONS], ym[NUM_TITLE_BALLOONS],
  2085.     color[NUM_TITLE_BALLOONS], bumped[NUM_TITLE_BALLOONS];
  2086.   SDL_Rect src, dest;
  2087.   SDLKey key;
  2088.   
  2089.  
  2090.   /* Show mouse pointer: */
  2091.   
  2092.   SDL_ShowCursor(1);
  2093.   
  2094.   
  2095.   /* Draw background: */
  2096.  
  2097.   SDL_BlitSurface(images[IMG_TITLE], NULL, screen, NULL);
  2098.   SDL_Flip(screen);
  2099.   
  2100.   
  2101.   /* Reset highlight info: */
  2102.   
  2103.   highlight_x = -1;
  2104.   highlight_y = -1;
  2105.   highlight_w = -1;
  2106.   highlight_h = -1;
  2107.  
  2108.   old_highlight_x = -1;
  2109.   old_highlight_y = -1;
  2110.   old_highlight_w = -1;
  2111.   old_highlight_h = -1;
  2112.   
  2113.   
  2114.   /* Set balloon positions, directions and colors: */
  2115.   
  2116.   for (i = 0; i < NUM_TITLE_BALLOONS; i++)
  2117.     {
  2118.       x[i] = rand() % (640 - 32);
  2119.       y[i] = rand() % (480 - 32);
  2120.       
  2121.       xm[i] = (rand() % 5) + 1;
  2122.       
  2123.       if ((rand() % 2) == 0)
  2124.     xm[i] = -xm[i];
  2125.       
  2126.       ym[i] = (rand() % 5) + 1;
  2127.  
  2128.       if ((rand() % 2) == 0)
  2129.     ym[i] = -ym[i];
  2130.       
  2131.       color[i] = ((rand() % 8) * 6) + IMG_BALLOON_RED_LEFT_0;
  2132.       bumped[i] = 0;
  2133.     }
  2134.   
  2135.   highscore_effect = 0;
  2136.   
  2137.   
  2138.   /* --- MAIN TITLE LOOP --- */
  2139.   
  2140.   done = 0;
  2141.   show_highscores = 0;
  2142.   quit = 0;
  2143.   frame = 0;
  2144.   
  2145.   text_x = -640;
  2146.   text_xm = 36;
  2147.   text_img = 0;
  2148.   text_time = 0;
  2149.   
  2150.   do
  2151.     {
  2152.       frame++;
  2153.       
  2154.       
  2155.       /* Handle events: */
  2156.       
  2157.       while (SDL_PollEvent(&event))
  2158.     {
  2159.       if (event.type == SDL_QUIT)
  2160.         {
  2161.           /* Quit event!  */
  2162.           
  2163.           quit = 1;
  2164.         }
  2165.       else if (event.type == SDL_KEYDOWN)
  2166.         {
  2167.           /* A keypress! */
  2168.           
  2169.           key = event.key.keysym.sym;
  2170.           
  2171.           if (key == SDLK_ESCAPE)
  2172.         {
  2173.           /* Escape: done: */
  2174.           
  2175.           quit = 1;
  2176.         }
  2177.         }
  2178.       else if (event.type == SDL_MOUSEBUTTONDOWN)
  2179.         {
  2180.           /* Click: */
  2181.           
  2182.           if (event.button.x >= 16 && event.button.x <= 16 + 238 &&
  2183.           event.button.y >= 283 && event.button.y <= 283 + 27)
  2184.         {
  2185.           /* Start one-player game: */
  2186.           
  2187.           num_players = 1;
  2188.           done = 1;
  2189.         }    
  2190.           else if (event.button.x >= 16 && event.button.x <= 16 + 264 &&
  2191.           event.button.y >= 310 && event.button.y <= 310 + 27)
  2192.         {
  2193.           /* Start two-player game: */
  2194.           
  2195.           num_players = 2;
  2196.           coop = 0;
  2197.           done = 1;
  2198.         }
  2199.           else if (event.button.x >= 16 && event.button.x <= 16 + 356 &&
  2200.           event.button.y >= 337 && event.button.y <= 337 + 27)
  2201.         {
  2202.           /* Start two-player coop game: */
  2203.           
  2204.           num_players = 2;
  2205.           coop = 1;
  2206.           done = 1;
  2207.         }
  2208.           else if (event.button.x <= 207 &&
  2209.           event.button.y >= 371 && event.button.y <= 371 + 27)
  2210.         {
  2211.           /* Toggle Barriers: */
  2212.           
  2213.           barriers = !barriers;
  2214.           playsound(SND_TEETER2 - barriers);
  2215.         }
  2216.           else if (event.button.x <= 374 &&
  2217.           event.button.y >= 398 && event.button.y <= 398 + 27)
  2218.         {
  2219.           /* Toggle Bouncy Balloons: */
  2220.           
  2221.           bouncy = !bouncy;
  2222.           playsound(SND_TEETER2 - bouncy);
  2223.         }
  2224.           else if (event.button.x <= 234 &&
  2225.           event.button.y >= 425 && event.button.y <= 425 + 27)
  2226.         {
  2227.           /* Toggle Clear-All Mode: */
  2228.           
  2229.           clearall = !clearall;
  2230.           playsound(SND_TEETER2 - clearall);
  2231.         }
  2232.           else if (event.button.x >= 559 && event.button.x <= 559 + 73 &&
  2233.                event.button.y >= 284 && event.button.y <= 284 + 52)
  2234.         {
  2235.           /* Set SFX Volume: */
  2236.           
  2237.           sfx_vol = (sfx_vol + 1) % 4;
  2238.           
  2239. #ifndef NOSOUND
  2240.           if (use_sound)
  2241.             Mix_Volume(-1, (sfx_vol * MIX_MAX_VOLUME) / 3);
  2242. #endif
  2243.           
  2244.           playsound(SND_POP);
  2245.         }
  2246.           else if (event.button.x >= 512 && event.button.x <= 512 + 121 &&
  2247.                event.button.y >= 336 && event.button.y <= 336 + 52)
  2248.         {
  2249.           /* Set Music Volume: */
  2250.           
  2251.           music_vol = (music_vol + 1) % 4;
  2252.           
  2253. #ifndef NOSOUND
  2254.           if (use_sound)
  2255.             Mix_VolumeMusic((music_vol * MIX_MAX_VOLUME) / 3);
  2256. #endif
  2257.           
  2258.           playsound(SND_POP);
  2259.         }
  2260.           else if (event.button.x >= 440 && event.button.x <= 440 + 195 &&
  2261.                event.button.y >= 398 && event.button.y <= 398 + 29)
  2262.         {
  2263.           /* High score screen: */
  2264.           
  2265.           playsound(SND_HIGHSCORE);
  2266.           
  2267.           done = 1;
  2268.           show_highscores = 1;
  2269.         }
  2270.           else if (event.button.x >= 535 && event.button.x <= 535 + 100 &&
  2271.                event.button.y >= 429 && event.button.y <= 429 + 29)
  2272.         {
  2273.           /* Exit: */
  2274.           
  2275.           quit = 1;
  2276.         }
  2277.         }
  2278.       else if (event.type == SDL_MOUSEMOTION)
  2279.         {
  2280.           /* Mouse motion.  Highlight options: */
  2281.           
  2282.           if (event.motion.x >= 16 && event.motion.x <= 16 + 238 &&
  2283.           event.motion.y >= 283 && event.motion.y <= 283 + 27)
  2284.         {
  2285.           /* Start one-player game: */
  2286.           
  2287.           highlight_x = 16;
  2288.           highlight_y = 283;
  2289.           highlight_w = 238;
  2290.           highlight_h = 27;
  2291.         }    
  2292.           else if (event.motion.x >= 16 && event.motion.x <= 16 + 264 &&
  2293.           event.motion.y >= 310 && event.motion.y <= 310 + 27)
  2294.         {
  2295.           /* Start two-player game: */
  2296.           
  2297.           highlight_x = 16;
  2298.           highlight_y = 310;
  2299.           highlight_w = 264;
  2300.           highlight_h = 27;
  2301.         }
  2302.           else if (event.motion.x >= 16 && event.motion.x <= 16 + 356 &&
  2303.           event.motion.y >= 337 && event.motion.y <= 337 + 27)
  2304.         {
  2305.           /* Start two-player coop game: */
  2306.           
  2307.           highlight_x = 16;
  2308.           highlight_y = 337;
  2309.           highlight_w = 356;
  2310.           highlight_h = 27;
  2311.         }
  2312.           else if (event.motion.x <= 207 &&
  2313.           event.motion.y >= 371 && event.motion.y <= 371 + 27)
  2314.         {
  2315.           /* Toggle Barriers: */
  2316.           
  2317.           highlight_x = 0;
  2318.           highlight_y = 371;
  2319.           highlight_w = 207;
  2320.           highlight_h = 27;
  2321.         }
  2322.           else if (event.motion.x <= 374 &&
  2323.           event.motion.y >= 398 && event.motion.y <= 398 + 27)
  2324.         {
  2325.           /* Toggle Bouncy Balloons: */
  2326.           
  2327.           highlight_x = 0;
  2328.           highlight_y = 398;
  2329.           highlight_w = 374;
  2330.           highlight_h = 27;
  2331.         }
  2332.           else if (event.motion.x <= 234 &&
  2333.           event.motion.y >= 425 && event.motion.y <= 425 + 27)
  2334.         {
  2335.           /* Toggle Clear-All Mode: */
  2336.           
  2337.           highlight_x = 0;
  2338.           highlight_y = 425;
  2339.           highlight_w = 234;
  2340.           highlight_h = 27;
  2341.         }
  2342.           else if (event.motion.x >= 559 && event.motion.x <= 559 + 73 &&
  2343.                event.motion.y >= 284 && event.motion.y <= 284 + 52)
  2344.         {
  2345.           /* Set SFX Volume: */
  2346.  
  2347.           highlight_x = 559;
  2348.           highlight_y = 284;
  2349.           highlight_w = 73;
  2350.           highlight_h = 52;
  2351.         }
  2352.           else if (event.motion.x >= 512 && event.motion.x <= 512 + 121 &&
  2353.                event.motion.y >= 336 && event.motion.y <= 336 + 52)
  2354.         {
  2355.           /* Set Music Volume: */
  2356.           
  2357.           highlight_x = 512;
  2358.           highlight_y = 336;
  2359.           highlight_w = 121;
  2360.           highlight_h = 52;
  2361.         }
  2362.           else if (event.motion.x >= 440 && event.motion.x <= 440 + 195 &&
  2363.                event.motion.y >= 398 && event.motion.y <= 398 + 29)
  2364.         {
  2365.           /* Hiscore: */
  2366.           
  2367.           highlight_x = 440;
  2368.           highlight_y = 398;
  2369.           highlight_w = 195;
  2370.           highlight_h = 29;
  2371.         }
  2372.           else if (event.motion.x >= 535 && event.motion.x <= 535 + 100 &&
  2373.                event.motion.y >= 429 && event.motion.y <= 429 + 29)
  2374.         {
  2375.           /* Exit: */
  2376.           
  2377.           highlight_x = 535;
  2378.           highlight_y = 429;
  2379.           highlight_w = 100;
  2380.           highlight_h = 29;
  2381.         }
  2382.           else
  2383.         {
  2384.           highlight_x = -1;
  2385.         }
  2386.         }
  2387.     }
  2388.       
  2389.       
  2390.       SDL_Delay(30);
  2391.       
  2392.  
  2393.       /* Erase highlight: */
  2394.       
  2395.       if (old_highlight_x != highlight_x ||
  2396.       old_highlight_y != highlight_y)
  2397.     {
  2398.       if (old_highlight_x != -1)
  2399.         {
  2400.           erase(old_highlight_x, old_highlight_y,
  2401.             old_highlight_w, old_highlight_h,
  2402.             IMG_TITLE);
  2403.         }
  2404.       
  2405.       old_highlight_x = highlight_x;
  2406.       old_highlight_y = highlight_y;
  2407.       old_highlight_w = highlight_w;
  2408.       old_highlight_h = highlight_h;
  2409.     }
  2410.       
  2411.       
  2412.       /* Erase the balloons: */
  2413.       
  2414.       if (use_low == 0)
  2415.     {
  2416.       for (i = 0; i < NUM_TITLE_BALLOONS; i++)
  2417.         {
  2418.           erase(x[i], y[i], 32, 32, IMG_TITLE);
  2419.         }
  2420.     }
  2421.       
  2422.       
  2423.       /* Erase credits: */
  2424.       
  2425.       erase(0, 252, 640, 32, IMG_TITLE);
  2426.       
  2427.       
  2428.       /* Move the balloons: */
  2429.       
  2430.       for (i = 0; i < NUM_TITLE_BALLOONS; i++)
  2431.     {
  2432.       /* Move the balloon: */
  2433.       
  2434.       x[i] = x[i] + xm[i];
  2435.       y[i] = y[i] + ym[i];
  2436.       
  2437.  
  2438.       /* Apply gravity: */
  2439.       
  2440.       if ((frame % 3) == 0)
  2441.         {
  2442.           ym[i] = ym[i] + 1;
  2443.           
  2444.           if (ym[i] > 16)
  2445.         ym[i] = 16;
  2446.         }
  2447.       
  2448.       
  2449.       /* Reset 'bumped' flag: */
  2450.       
  2451.       bumped[i] = 0;
  2452.     }
  2453.  
  2454.       
  2455.       /* Make balloons bounce into each other: */
  2456.       
  2457.       for (i = 0; i < NUM_TITLE_BALLOONS; i++)
  2458.     {
  2459.       for (j = 0; j < NUM_TITLE_BALLOONS; j++)
  2460.         {
  2461.           if (j != i && bumped[j] == 0 && bumped[i] == 0)
  2462.         {
  2463.           if (x[i] > x[j] - 32 &&
  2464.               x[i] < x[j] + 32 &&
  2465.               y[i] > y[j] - 32 &&
  2466.               y[i] < y[j] + 32)
  2467.             {
  2468.               x[i] = x[i] - (xm[i] * 2) / 3;
  2469.               y[i] = y[i] - (ym[i] * 2) / 3;
  2470.               
  2471.               tmp = xm[i];
  2472.               xm[i] = xm[j];
  2473.               xm[j] = tmp;
  2474.  
  2475.               tmp = ym[i];
  2476.               ym[i] = ym[j];
  2477.               ym[j] = tmp;
  2478.               
  2479.               bumped[i] = 1;
  2480.               bumped[j] = 1;
  2481.             }
  2482.         }
  2483.         }
  2484.     }
  2485.  
  2486.  
  2487.       /* Keep balloons in bounds: */
  2488.       
  2489.       for (i = 0; i < NUM_TITLE_BALLOONS; i++)
  2490.     {
  2491.       if (x[i] <= 0)
  2492.         {
  2493.           xm[i] = (rand() % 5) + 1;
  2494.           x[i] = 0;
  2495.         }
  2496.       else if (x[i] >= 640 - 32)
  2497.         {
  2498.           xm[i] = -((rand() % 5) + 1);
  2499.           x[i] = 640 - 32;
  2500.         }
  2501.       
  2502.       if (y[i] <= 0)
  2503.         {
  2504.           ym[i] = (rand() % 5) + 1;
  2505.           y[i] = 0;
  2506.         }
  2507.       else if (y[i] >= 480 - 32)
  2508.         {
  2509.           ym[i] = -(ym[i]);
  2510.           y[i] = 480 - 32;
  2511.         }
  2512.     }
  2513.       
  2514.       
  2515.       /* Handle credits: */
  2516.       
  2517.       if (text_x < 0)
  2518.     {
  2519.       text_x = text_x + text_xm;
  2520.       
  2521.       if (text_x >= 0)
  2522.         {
  2523.           text_x = 0;
  2524.           text_xm = 0;
  2525.         }
  2526.       else
  2527.         text_xm--;
  2528.     }
  2529.       else if (text_x == 0 && text_time < 100)
  2530.     {
  2531.       text_time++;
  2532.       text_xm = 0;
  2533.     }
  2534.       else if (text_x < 640)
  2535.     {
  2536.       text_x = text_x + text_xm;
  2537.       text_xm++;
  2538.     }
  2539.       else
  2540.     {
  2541.       text_img = (text_img + 1) % 3;
  2542.       text_x = -640;
  2543.       text_xm = 36;
  2544.       text_time = 0;
  2545.     }
  2546.       
  2547.       
  2548.       /* Draw highlight: */
  2549.       
  2550.       if (highlight_x != -1)
  2551.     {
  2552.       src.x = highlight_x;
  2553.       src.y = highlight_y - 275;
  2554.       src.w = highlight_w;
  2555.       src.h = highlight_h;
  2556.       
  2557.       dest.x = highlight_x;
  2558.       dest.y = highlight_y;
  2559.       dest.w = highlight_w;
  2560.       dest.h = highlight_h;
  2561.       
  2562.       SDL_BlitSurface(images[IMG_TITLE_HIGHLIGHTS], &src,
  2563.               screen, &dest);
  2564.     }
  2565.       
  2566.       
  2567.       /* Draw whether options are on: */
  2568.       
  2569.       if (barriers)
  2570.     draw(0, 376, IMG_LIGHT_ON);
  2571.       else
  2572.     draw(0, 376, IMG_LIGHT_OFF);
  2573.       
  2574.       if (bouncy)
  2575.     draw(0, 404, IMG_LIGHT_ON);
  2576.       else
  2577.     draw(0, 404, IMG_LIGHT_OFF);
  2578.  
  2579.       if (clearall)
  2580.     draw(0, 429, IMG_LIGHT_ON);
  2581.       else
  2582.     draw(0, 429, IMG_LIGHT_OFF);
  2583.       
  2584.       for (i = 0; i < 3; i++)
  2585.     {
  2586.       if (sfx_vol > i)
  2587.         draw(583 + i * 16, 311, IMG_LIGHT_ON);
  2588.       else
  2589.         draw(583 + i * 16, 311, IMG_LIGHT_OFF);
  2590.  
  2591.       if (music_vol > i)
  2592.         draw(583 + i * 16, 363, IMG_LIGHT_ON);
  2593.       else
  2594.         draw(583 + i * 16, 363, IMG_LIGHT_OFF);    
  2595.     }
  2596.       
  2597.       
  2598.       /* Draw the balloons: */
  2599.       
  2600.       if (use_low == 0)
  2601.     {
  2602.       for (i = 0; i < NUM_TITLE_BALLOONS; i++)
  2603.         {
  2604.           if (xm[i] > 0)
  2605.         draw(x[i], y[i], color[i] + 2 + (rand() % 2));
  2606.           else
  2607.         draw(x[i], y[i], color[i] + (rand() % 2));
  2608.         }
  2609.     }
  2610.       
  2611.       
  2612.       /* Draw the credits: */
  2613.       
  2614.       draw(text_x, 252, IMG_PROGRAMMER + text_img);
  2615.       
  2616.       
  2617.       /* Update the screen: */
  2618.       
  2619.       SDL_Flip(screen);
  2620.       
  2621.       
  2622.       /* Keep playing music: */
  2623.       
  2624. #ifndef NOSOUND
  2625.       if (use_sound == 1)
  2626.     {
  2627.       if (!Mix_PlayingMusic())
  2628.         {
  2629.           Mix_PlayMusic(mus_title, 0);
  2630.           Mix_VolumeMusic((music_vol * MIX_MAX_VOLUME) / 3);
  2631.         }
  2632.     }
  2633. #endif
  2634.     }
  2635.   while (done == 0 && quit == 0);
  2636.   
  2637.   
  2638.   /* Play a pop noise: */
  2639.   
  2640.   playsound(SND_POP);
  2641.   
  2642.   
  2643.   /* Stop title music: */
  2644.   
  2645. #ifndef NOSOUND
  2646.   if (use_sound == 1)
  2647.     {
  2648.       Mix_HaltMusic();
  2649.     }
  2650. #endif  
  2651.   
  2652.   return(quit);
  2653. }
  2654.  
  2655.  
  2656. /* Set video mode: */
  2657. /* Mattias Engdegard <f91-men@nada.kth.se> */
  2658.  
  2659. SDL_Surface * set_vid_mode(unsigned flags)
  2660. {
  2661.   /* Prefer 16bpp, but also prefer native modes to emulated 16bpp. */
  2662.   
  2663.   int depth;
  2664.   
  2665.   depth = SDL_VideoModeOK(640, 480, 16, flags);
  2666.   return depth ? SDL_SetVideoMode(640, 480, depth, flags) : NULL;
  2667. }
  2668.  
  2669.  
  2670.  
  2671. /* Set up screen, load graphics, sound and music: */
  2672.  
  2673. void setup(void)
  2674. {
  2675.   int i, col;
  2676.   SDL_Surface * image;
  2677.   SDL_Rect dest;
  2678.   
  2679.   
  2680.   /* Init SDL Video: */
  2681.   
  2682.   if (SDL_Init(SDL_INIT_VIDEO) < 0)
  2683.     {
  2684.       fprintf(stderr,
  2685.               "\nError: I could not initialize video!\n"
  2686.               "The Simple DirectMedia error that occured was:\n"
  2687.               "%s\n\n", SDL_GetError());
  2688.       exit(1);
  2689.     }
  2690.  
  2691.  
  2692.   /* Init Joystick: */
  2693.   
  2694. #ifdef JOY_YES
  2695.   if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
  2696.     {
  2697.       fprintf(stderr, "Warning: I could not initialize joystick!\n"
  2698.           "The Simple DirectMedia error that occured was:\n"
  2699.           "%s\n\n", SDL_GetError());
  2700.       
  2701.       use_joystick = 0;
  2702.     }
  2703.   else
  2704.     {
  2705.       /* Open joystick: */
  2706.       
  2707.       if (SDL_NumJoysticks() <= 0)
  2708.     {
  2709.       fprintf(stderr, "Warning: No joysticks are available.\n");
  2710.       
  2711.       use_joystick = 0;
  2712.     }
  2713.       else
  2714.     {
  2715.       js = SDL_JoystickOpen(0);
  2716.       
  2717.       if (js == NULL)
  2718.         {
  2719.           fprintf(stderr, "Warning: Could not open joystick 1.\n"
  2720.               "The Simple DirectMedia error that occured was:\n"
  2721.               "%s\n\n", SDL_GetError());
  2722.           
  2723.           use_joystick = 0;
  2724.         }
  2725.       else
  2726.         {
  2727.           /* Check for proper joystick configuration: */
  2728.           
  2729.           if (SDL_JoystickNumAxes(js) < 1)
  2730.         {
  2731.           fprintf(stderr,
  2732.               "Warning: Joystick does not have enough axes!\n");
  2733.           
  2734.           use_joystick = 0;
  2735.         }
  2736.           else
  2737.         {
  2738.           if (SDL_JoystickNumButtons(js) < 1)
  2739.             {
  2740.               fprintf(stderr,
  2741.                   "Warning: "
  2742.                   "Joystick does not have enough buttons!\n");
  2743.               
  2744.               use_joystick = 0;
  2745.             }
  2746.         }
  2747.         }
  2748.     }
  2749.     }
  2750. #endif
  2751.   
  2752.   
  2753.   /* Init SDL Audio: */
  2754.   
  2755.   if (use_sound == 1)
  2756.     {
  2757.       if (SDL_Init(SDL_INIT_AUDIO) < 0)
  2758.         {
  2759.           fprintf(stderr,
  2760.                   "\nWarning: I could not initialize audio!\n"
  2761.                   "The Simple DirectMedia error that occured was:\n"
  2762.                   "%s\n\n", SDL_GetError());
  2763.           use_sound = 0;
  2764.         }
  2765.     }
  2766.   
  2767.   
  2768.   /* Open sound: */
  2769.   
  2770. #ifndef NOSOUND
  2771.   if (use_sound == 1)
  2772.     {
  2773.       if (Mix_OpenAudio(11025, AUDIO_S16, 2, 512) < 0)
  2774.         {
  2775.           fprintf(stderr,
  2776.                   "\nWarning: I could not set up audio for 11025 Hz "
  2777.                   "16-bit stereo.\n"
  2778.                   "The Simple DirectMedia error that occured was:\n"
  2779.                   "%s\n\n", SDL_GetError());
  2780.           use_sound = 0;
  2781.         }
  2782.     }
  2783. #endif
  2784.  
  2785.  
  2786.   /* Open display: */
  2787.   
  2788.   if (use_fullscreen == 1)
  2789.     {
  2790.       screen = set_vid_mode(SDL_FULLSCREEN | SDL_HWSURFACE);
  2791.       if (screen == NULL)
  2792.         {
  2793.           fprintf(stderr,
  2794.                   "\nWarning: I could not set up fullscreen video for "
  2795.                   "640x480 mode.\n"
  2796.                   "The Simple DirectMedia error that occured was:\n"
  2797.                   "%s\n\n", SDL_GetError());
  2798.           use_fullscreen = 0;
  2799.         }
  2800.     }
  2801.   
  2802.   if (use_fullscreen == 0)
  2803.     {
  2804.       screen = set_vid_mode(0);
  2805.       
  2806.       if (screen == NULL)
  2807.         {
  2808.           fprintf(stderr,
  2809.                   "\nError: I could not set up video for 640x480 mode.\n"
  2810.                   "The Simple DirectMedia error that occured was:\n"
  2811.                   "%s\n\n", SDL_GetError());
  2812.           exit(1);
  2813.         }
  2814.     }
  2815.   
  2816.   
  2817.   /* Set icon image: */
  2818.   
  2819.   seticon();
  2820.  
  2821.   
  2822.   /* Set window manager stuff: */
  2823.   
  2824.   SDL_WM_SetCaption("Circus Linux!", "Circus Linux!");
  2825.   
  2826.   
  2827.   /* Load graphics: */
  2828.   
  2829.   for (i = 0; i < NUM_IMAGES; i++)
  2830.     {
  2831.       /* Load image file: */
  2832.       
  2833.       image = IMG_Load(image_names[i]);
  2834.  
  2835.       if (image == NULL)
  2836.         {
  2837.           fprintf(stderr,
  2838.                   "\nError: I couldn't load a graphics file:\n"
  2839.                   "%s\n"
  2840.                   "The Simple DirectMedia error that occured was:\n"
  2841.                   "%s\n\n", image_names[i], SDL_GetError());
  2842.           exit(1);
  2843.         }
  2844.       
  2845.       
  2846.       /* Set transparency: */
  2847.       
  2848.       if (SDL_SetColorKey(image, (SDL_SRCCOLORKEY | SDL_RLEACCEL),
  2849.                           SDL_MapRGB(image -> format,
  2850.                                      0xFF, 0xFF, 0xFF)) == -1)
  2851.         {
  2852.           fprintf(stderr,
  2853.                   "\nError: I could not set the color key for the file:\n"
  2854.                   "%s\n"
  2855.                   "The Simple DirectMedia error that occured was:\n"
  2856.                   "%s\n\n", image_names[i], SDL_GetError());
  2857.           exit(1);
  2858.         }
  2859.  
  2860.       images[i] = SDL_DisplayFormat(image);
  2861.       if (images[i] == NULL)
  2862.         {
  2863.           fprintf(stderr,
  2864.                   "\nError: I couldn't convert a file to the display format:\n"
  2865.                   "%s\n"
  2866.                   "The Simple DirectMedia error that occured was:\n"
  2867.                   "%s\n\n", image_names[i], SDL_GetError());
  2868.           exit(1);
  2869.         }
  2870.       
  2871.       
  2872.       SDL_FreeSurface(image);
  2873.       
  2874.       
  2875.       /* Draw percentage bar: */
  2876.       
  2877.       dest.x = 0;
  2878.       dest.y = 470;
  2879.       dest.w = (640 * i) / NUM_IMAGES;
  2880.       dest.h = 10;
  2881.       
  2882.       col = (255 * i) / NUM_IMAGES;
  2883.       
  2884.       SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, col, col, col));
  2885.       SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
  2886.       SDL_Delay(1);
  2887.     }
  2888.   
  2889.   
  2890. #ifndef NOSOUND
  2891.   if (use_sound == 1)
  2892.     {
  2893.       /* Load sounds: */
  2894.       
  2895.       for (i = 0; i < NUM_SOUNDS; i++)
  2896.         {
  2897.           sounds[i] = Mix_LoadWAV(sound_names[i]);
  2898.           if (sounds[i] == NULL)
  2899.             {
  2900.               fprintf(stderr,
  2901.                       "\nError: I could not load the sound file:\n"
  2902.                       "%s\n"
  2903.                       "The Simple DirectMedia error that occured was:\n"
  2904.                       "%s\n\n", sound_names[i], SDL_GetError());
  2905.               exit(1);
  2906.             }
  2907.         }
  2908.       
  2909.       
  2910.       /* Load musics: */
  2911.       
  2912.       /* (title) */
  2913.       
  2914.       mus_title = Mix_LoadMUS(MUS_TITLE);
  2915.       if (mus_title == NULL)
  2916.     {
  2917.       fprintf(stderr,
  2918.           "\nError: I could not load the music file:\n"
  2919.           "%s\n"
  2920.           "The Simple DirectMedia error that occured was:\n"
  2921.           "%s\n\n", MUS_TITLE, SDL_GetError());
  2922.       exit(1);
  2923.     }
  2924.  
  2925.       /* (game) */
  2926.       
  2927.       mus_game = Mix_LoadMUS(MUS_GAME);
  2928.       if (mus_game == NULL)
  2929.     {
  2930.       fprintf(stderr,
  2931.           "\nError: I could not load the music file:\n"
  2932.           "%s\n"
  2933.           "The Simple DirectMedia error that occured was:\n"
  2934.           "%s\n\n", MUS_GAME, SDL_GetError());
  2935.       exit(1);
  2936.     }
  2937.  
  2938.       /* (gameover) */
  2939.       
  2940.       mus_gameover = Mix_LoadMUS(MUS_GAMEOVER);
  2941.       if (mus_gameover == NULL)
  2942.     {
  2943.       fprintf(stderr,
  2944.           "\nError: I could not load the music file:\n"
  2945.           "%s\n"
  2946.           "The Simple DirectMedia error that occured was:\n"
  2947.           "%s\n\n", MUS_GAMEOVER, SDL_GetError());
  2948.       exit(1);
  2949.     }
  2950.  
  2951.       /* (hiscore) */
  2952.  
  2953.       mus_hiscore = Mix_LoadMUS(MUS_HISCORE);
  2954.       if (mus_hiscore == NULL)
  2955.     {
  2956.       fprintf(stderr,
  2957.           "\nError: I could not load the music file:\n"
  2958.           "%s\n"
  2959.           "The Simple DirectMedia error that occured was:\n"
  2960.           "%s\n\n", MUS_HISCORE, SDL_GetError());
  2961.       exit(1);
  2962.     }
  2963.  
  2964.       /* (hiscore screen) */
  2965.  
  2966.       mus_hiscreen = Mix_LoadMUS(MUS_HISCORESCREEN);
  2967.       if (mus_hiscreen == NULL)
  2968.     {
  2969.       fprintf(stderr,
  2970.           "\nError: I could not load the music file:\n"
  2971.           "%s\n"
  2972.           "The Simple DirectMedia error that occured was:\n"
  2973.           "%s\n\n", MUS_HISCORESCREEN, SDL_GetError());
  2974.       exit(1);
  2975.     }
  2976.     }
  2977. #endif
  2978.  
  2979.   
  2980.   
  2981.   /* Seed random generator: */
  2982.   
  2983.   srand(SDL_GetTicks());
  2984. }
  2985.  
  2986.  
  2987. /* Erase part of the screen back to the background: */
  2988.  
  2989. void erase(int x, int y, int w, int h, int bkgd)
  2990. {
  2991.   SDL_Rect dest;
  2992.   
  2993.   dest.x = x;
  2994.   dest.y = y;
  2995.   dest.w = w;
  2996.   dest.h = h;
  2997.   
  2998.   if (use_low == 0 || bkgd == IMG_TITLE)
  2999.     SDL_BlitSurface(images[bkgd], &dest, screen, &dest);
  3000.   else
  3001.     SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 50, 50, 80));
  3002. }
  3003.  
  3004.  
  3005. /* Draw an object: */
  3006.  
  3007. void draw(int x, int y, int pict)
  3008. {
  3009.   SDL_Rect src, dest;
  3010.   
  3011.   src.x = 0;
  3012.   src.y = 0;
  3013.   src.w = images[pict] -> w;
  3014.   src.h = images[pict] -> h;
  3015.   
  3016.   dest.x = x;
  3017.   dest.y = y;
  3018.   dest.w = src.w;
  3019.   dest.h = src.h;
  3020.   
  3021.   SDL_BlitSurface(images[pict], &src, screen, &dest);
  3022. }
  3023.  
  3024.  
  3025. /* Draw a clown: */
  3026.  
  3027. void drawclown(int x, int y, int side,
  3028.            int left_arm, int right_arm,
  3029.            int left_leg, int right_leg)
  3030. {
  3031.   draw(x, y, IMG_CLOWN_BODY_LEFT + side);
  3032.   
  3033.   if (left_arm != -1)
  3034.     draw(x, y, IMG_CLOWN_LEFT_ARM_0 + left_arm);
  3035.   
  3036.   if (right_arm != -1)
  3037.     draw(x, y, IMG_CLOWN_RIGHT_ARM_0 + right_arm);
  3038.   
  3039.   draw(x, y, IMG_CLOWN_LEFT_LEG_0 + left_leg);
  3040.   draw(x, y, IMG_CLOWN_RIGHT_LEG_0 + right_leg);
  3041. }
  3042.  
  3043.  
  3044. /* Clear rectangle list: */
  3045.  
  3046. void clearrects(void)
  3047. {
  3048.   num_rects = 0;
  3049. }
  3050.  
  3051.  
  3052. /* Add a rectangle: */
  3053.  
  3054. void addrect(int x, int y, int w, int h)
  3055. {
  3056.   rects[num_rects].x = x;
  3057.   rects[num_rects].y = y;
  3058.   rects[num_rects].w = w;
  3059.   rects[num_rects].h = h;
  3060.   
  3061.   if (num_rects < MAX_RECTS - 1)
  3062.     num_rects++;
  3063. }
  3064.  
  3065.  
  3066. /* Activate a clown: */
  3067.  
  3068. void newclown(void)
  3069. {
  3070.   /* Activate the clown: */
  3071.   
  3072.   flying_active = 1;
  3073.   flying_splat = 0;
  3074.   
  3075.   
  3076.   /* Start somewhere: */
  3077.   
  3078.   flying_x = 608 * (rand() % 2);
  3079.   flying_y = FLYING_START_Y;
  3080.   
  3081.   if (flying_x == 0)
  3082.     flying_dir = RIGHT;
  3083.   else
  3084.     flying_dir = LEFT;
  3085.   
  3086.   
  3087.   /* Speed: */
  3088.   
  3089.   flying_xm = 0;
  3090.   flying_ym = FLYING_START_YM;
  3091.   
  3092.   
  3093.   /* Set limbs randomly: */
  3094.   
  3095.   flying_left_arm = rand() % 3;
  3096.   flying_right_arm = rand() % 3;
  3097.   flying_left_leg = rand() % 2;
  3098.   flying_right_leg = rand() % 2;
  3099. }
  3100.  
  3101.  
  3102. /* Play a sound: */
  3103.  
  3104. void playsound(int snd)
  3105. {
  3106. #ifndef NOSOUND
  3107.   if (use_sound)
  3108.     Mix_PlayChannel(-1, sounds[snd], 0);
  3109. #endif
  3110. }
  3111.  
  3112.  
  3113. /* Reset a row of balloons: */
  3114.  
  3115. void resetballoons(int player, int row)
  3116. {
  3117.   int i;
  3118.   
  3119.   for (i = 0; i < 20; i++)
  3120.     balloons[player][row][i] = NORMAL;
  3121. }
  3122.  
  3123.  
  3124. /* Draw a balloon: */
  3125.  
  3126. void drawballoon(int player, int x, int y, int off)
  3127. {
  3128.   SDL_Rect dest;
  3129.   int img;
  3130.   
  3131.   
  3132.   img = -1;
  3133.   
  3134.   if (balloons[player][y][x] != GONE)
  3135.     {
  3136.       /* What color balloon? */
  3137.       
  3138.       img = IMG_BALLOON_RED_LEFT_0 + (balloon_colors[player][y] * 6);
  3139.       
  3140.       if (highscore_effect)
  3141.     img = IMG_BALLOON_RED_LEFT_0 + ((rand() % 8) * 6);
  3142.       
  3143.       
  3144.       /* Is it popping? */
  3145.       
  3146.       if (balloons[player][y][x] != NORMAL)
  3147.     {
  3148.       /* Yes: */
  3149.       
  3150.       img = img + 4;
  3151.       
  3152.       if (balloons[player][y][x] == POPPING0)
  3153.         img++;
  3154.     }
  3155.       else
  3156.     {
  3157.       /* No:  Wave string */
  3158.       
  3159.       img = img + (rand() % 2);
  3160.       
  3161.       
  3162.       /* What direction is it going? */
  3163.       
  3164.       img = img + ((y % 2) * 2);
  3165.     }
  3166.       
  3167.       
  3168.       /* Draw it! */
  3169.       
  3170.       dest.x = x * 32;
  3171.       
  3172.       /* (Shove it left or right 1/2 a space?) */
  3173.       
  3174.       if (off == 1)
  3175.     {
  3176.       if ((y % 2) == 0)
  3177.         dest.x = dest.x - 16;
  3178.       else
  3179.         dest.x = dest.x + 16;
  3180.     }
  3181.       
  3182.       dest.y = (y * 32) + 32;
  3183.       dest.w = 32;
  3184.       dest.h = 32;
  3185.       
  3186.       SDL_BlitSurface(images[img], NULL,
  3187.               screen, &dest);
  3188.     }
  3189. }
  3190.  
  3191.  
  3192. /* Update bits of the background that have changed: */
  3193.  
  3194. void update_background(int which)
  3195. {
  3196.   int i;
  3197.   SDL_Rect rect;
  3198.   
  3199.   for (i = 0; i < NUM_BACKGROUND_CHANGES; i++)
  3200.     {
  3201.       rect.x = background_change_rects[i][0];
  3202.       rect.y = background_change_rects[i][1];
  3203.       rect.w = background_change_rects[i][2];
  3204.       rect.h = background_change_rects[i][3];
  3205.  
  3206.       SDL_BlitSurface(images[IMG_BACKGROUND_0 + which], &rect,
  3207.               screen, &rect);
  3208.       
  3209.       addrect(rect.x, rect.y, rect.w, rect.h);
  3210.    }
  3211. }
  3212.  
  3213.  
  3214. /* Draw a number on the screen: */
  3215.  
  3216. void drawnumber(int x, int y, int v, int img)
  3217. {
  3218.   char str[16];
  3219.   int i;
  3220.   SDL_Rect src, dest;
  3221.   
  3222.   
  3223.   sprintf(str, "%d", v);
  3224.   
  3225.   for (i = 0; i < strlen(str); i++)
  3226.     {
  3227.       src.x = (str[i] - '0') * 32;
  3228.       src.y = 0;
  3229.       src.w = 32;
  3230.       src.h = 32;
  3231.       
  3232.       dest.x = x + (i * 32);
  3233.       dest.y = y;
  3234.       dest.w = 32;
  3235.       dest.h = 32;
  3236.       
  3237.       SDL_BlitSurface(images[img], &src,
  3238.               screen, &dest);
  3239.     }
  3240.   
  3241.   addrect(x, y, strlen(str) * 32, 32);
  3242. }
  3243.  
  3244.  
  3245. /* Draw text: */
  3246.  
  3247. void drawtext(int x, int y, char * str)
  3248. {
  3249.   int i;
  3250.   SDL_Rect src, dest;
  3251.   
  3252.   for (i = 0; i < strlen(str); i++)
  3253.     {
  3254.       if (str[i] >= 'A' && str[i] <= 'Z')
  3255.     {
  3256.       src.x = (str[i] - 'A') * 32;
  3257.       src.y = 0;
  3258.       src.w = 32;
  3259.       src.h = 32;
  3260.       
  3261.       dest.x = x + (i * 32);
  3262.       dest.y = y;
  3263.       dest.w = 32;
  3264.       dest.h = 32;
  3265.       
  3266.       SDL_BlitSurface(images[IMG_LETTERS], &src,
  3267.               screen, &dest);
  3268.     }
  3269.     }
  3270.   
  3271.   addrect(x, y, strlen(str) * 32, 32);
  3272. }
  3273.  
  3274.  
  3275. /* Draw a darkened area: */
  3276.  
  3277. void drawfuzz(int x, int y, int w, int h)
  3278. {
  3279.   int xx, yy;
  3280.   SDL_Rect src, dest;
  3281.   
  3282.   for (yy = y; yy < y + h; yy = yy + (images[IMG_FUZZ] -> h))
  3283.     {
  3284.       for (xx = x; xx < x + w; xx = xx + (images[IMG_FUZZ] -> w))
  3285.     {
  3286.       src.x = 0;
  3287.       src.y = 0;
  3288.       src.w = images[IMG_FUZZ] -> w;
  3289.       src.h = images[IMG_FUZZ] -> h;
  3290.       
  3291.       if (xx + src.w > x + w)
  3292.         src.w = x + w - xx;
  3293.       
  3294.       if (yy + src.h > y + h)
  3295.         src.h = y + h - yy;
  3296.       
  3297.       dest.x = xx;
  3298.       dest.y = yy;
  3299.       
  3300.       dest.w = src.w;
  3301.       dest.h = src.h;
  3302.       
  3303.       SDL_BlitSurface(images[IMG_FUZZ], &src,
  3304.               screen, &dest);
  3305.     }
  3306.     }
  3307.   
  3308.   addrect(x, y, w, h);
  3309. }
  3310.  
  3311.  
  3312. /* Set the application's icon: */
  3313.  
  3314. void seticon(void)
  3315. {
  3316.   int masklen;
  3317.   Uint8 * mask;
  3318.   SDL_Surface * icon;
  3319.   
  3320.   
  3321.   /* Load icon into a surface: */
  3322.   
  3323.   icon = IMG_Load(DATA_PREFIX "images/icon.png");
  3324.   if (icon == NULL)
  3325.     {
  3326.       fprintf(stderr,
  3327.               "\nError: I could not load the icon image: %s\n"
  3328.               "The Simple DirectMedia error that occured was:\n"
  3329.               "%s\n\n", DATA_PREFIX "images/icon.png", SDL_GetError());
  3330.       exit(1);
  3331.     }
  3332.   
  3333.   
  3334.   /* Create mask: */
  3335.   
  3336.   masklen = (((icon -> w) + 7) / 8) * (icon -> h);
  3337.   mask = malloc(masklen * sizeof(Uint8));
  3338.   memset(mask, 0xFF, masklen);
  3339.   
  3340.   
  3341.   /* Set icon: */
  3342.   
  3343.   SDL_WM_SetIcon(icon, mask);
  3344.   
  3345.   
  3346.   /* Free icon surface & mask: */
  3347.   
  3348.   free(mask);
  3349.   SDL_FreeSurface(icon);
  3350. }
  3351.  
  3352.  
  3353. /* Display usage screen: */
  3354.  
  3355. void usage(int ret)
  3356. {
  3357.   FILE * fs;
  3358.   
  3359.   if (ret == 1)
  3360.     fs = stderr;
  3361.   else
  3362.     fs = stdout;
  3363.   
  3364.   fprintf(fs, "\n"
  3365.       "Command-line options:\n"
  3366.       "\n"
  3367.       "  --disable-sound - Disable sound and music. (Also \"--nosound\" or \"-q\")\n"
  3368.       "  --fullscreen    - Display in full screen instead of a window, if possible.\n"
  3369.       "                    (Also \"-f\")\n"
  3370. #ifdef JOY_YES
  3371.       "  --digital       - Joystick will be seen as a digital game pad, not analog.\n"
  3372.       "                    (Also \"-d\")\n"
  3373. #endif
  3374.       "  --low           - Use less graphics to work on lower-end hardware.\n"
  3375.       "                    (Also \"-l\")\n"
  3376.       "  --help          - Display help on playing the game. (Also \"-h\")\n"
  3377.       "  --usage         - Display this usage information. (Also \"-u\")\n"
  3378.       "  --version       - Display what version you're running. (Also \"-v\")\n"
  3379.       "  --copying       - Display copying (GPL) information. (Also \"-c\")\n"
  3380.       "\n");
  3381.   
  3382.   exit(ret);
  3383. }
  3384.  
  3385.  
  3386. /* Open the option file: */
  3387.  
  3388. FILE * open_option_file(char * mode)
  3389. {
  3390.   char * filename;
  3391.   FILE * fi;
  3392. #ifdef LINUX
  3393.   char * home;
  3394. #endif
  3395.   
  3396.   
  3397. #ifdef LINUX
  3398.   /* Get home directory (from $HOME variable)... if we can't determine it,
  3399.      use the current directory ("."): */
  3400.  
  3401.   if (getenv("HOME") != NULL)
  3402.     home = getenv("HOME");
  3403.   else
  3404.     home = ".";
  3405.   
  3406.   
  3407.   /* Create the buffer for the filename: */
  3408.   
  3409.   filename = (char *) malloc(sizeof(char) * (strlen(home) +
  3410.                                              strlen("/.circuslinux") + 1));
  3411.   
  3412.   strcpy(filename, home);
  3413.   strcat(filename, "/.circuslinux");
  3414. #else
  3415.   filename = "circuslinux.dat";
  3416. #endif
  3417.   
  3418.   
  3419.   /* Try opening the file: */
  3420.   
  3421.   fi = fopen(filename, mode);
  3422.   
  3423.   if (fi == NULL)
  3424.     {
  3425.       fprintf(stderr, "\nWarning: I could not open the options file "); 
  3426.       
  3427.       if (strcmp(mode, "r") == 0)
  3428.         fprintf(stderr, "for read:");
  3429.       else if (strcmp(mode, "w") == 0)
  3430.         fprintf(stderr, "for write:");
  3431.       
  3432.      fprintf(stderr, "\n%s\n"
  3433.               "The error that occured was:\n"
  3434.               "%s\n\n", filename, strerror(errno));
  3435.     }
  3436.   
  3437.   return(fi);
  3438. }
  3439.  
  3440.  
  3441. /* Increment a player's high score: */
  3442.  
  3443. void addscore(int player, int inc)
  3444. {
  3445.   score[player] = score[player] + inc;
  3446.   
  3447.   
  3448.   /* Is this a high score? */
  3449.   
  3450.   if (score[player] >= highscore[highscore_index])
  3451.     {
  3452.       /* Did they just get this high score? */
  3453.       
  3454.       if (has_highscore != player)
  3455.     {
  3456.       has_highscore = player;
  3457.       playsound(SND_HIGHSCORE);
  3458.       highscore_effect = 50;
  3459.     }
  3460.       
  3461.       highscore[highscore_index] = score[player];
  3462.     }
  3463. }
  3464.  
  3465.  
  3466. /* Show high scores: */
  3467.  
  3468. int highscorescreen(void)
  3469. {
  3470.   SDL_Event event;
  3471.   int done, quit, i;
  3472.   
  3473.   
  3474.   /* Clear screen: */
  3475.   
  3476.   SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
  3477.   
  3478.   draw(0, 0, IMG_HIGHSCORE_TOP);
  3479.   draw(0, images[IMG_HIGHSCORE_TOP] -> h, IMG_HIGHSCORE_LEFT);
  3480.   
  3481.   
  3482.   /* Draw scores: */
  3483.   
  3484.   for (i = 0; i < 8; i++)
  3485.     {
  3486.       /* Score: */
  3487.       
  3488.       drawnumber(32, (images[IMG_HIGHSCORE_TOP] -> h) + (i * 32) + 16,
  3489.          highscore[i], IMG_NUMBERS_0 + (i % 2));
  3490.       
  3491.       
  3492.       /* Initials: */
  3493.       
  3494.       drawtext(224, (images[IMG_HIGHSCORE_TOP] -> h) + (i * 32) + 16,
  3495.            highscorer[i]);
  3496.       
  3497.       
  3498.       /* Modes: */
  3499.  
  3500.       /* (Barriers): */
  3501.       
  3502.       if (i >= 4)
  3503.     {
  3504.       draw(336, (images[IMG_HIGHSCORE_TOP] -> h) + (i * 32) + 24,
  3505.            IMG_LIGHT_ON);
  3506.     }
  3507.       else
  3508.     {
  3509.       draw(336, (images[IMG_HIGHSCORE_TOP] -> h) + (i * 32) + 24,
  3510.            IMG_LIGHT_OFF);
  3511.     }
  3512.       
  3513.       
  3514.       /* (Bouncy Balloons): */
  3515.       
  3516.       if (i == 2 || i == 3 || i == 6 || i == 7)
  3517.     {
  3518.       draw(444, (images[IMG_HIGHSCORE_TOP] -> h) + (i * 32) + 24,
  3519.            IMG_LIGHT_ON);
  3520.     }
  3521.       else
  3522.     {
  3523.       draw(444, (images[IMG_HIGHSCORE_TOP] -> h) + (i * 32) + 24,
  3524.            IMG_LIGHT_OFF);
  3525.     }
  3526.  
  3527.  
  3528.       /* (Clear All): */
  3529.       
  3530.       if ((i % 2) == 1)
  3531.     {
  3532.       draw(564, (images[IMG_HIGHSCORE_TOP] -> h) + (i * 32) + 24,
  3533.            IMG_LIGHT_ON);
  3534.     }
  3535.       else
  3536.     {
  3537.       draw(564, (images[IMG_HIGHSCORE_TOP] -> h) + (i * 32) + 24,
  3538.            IMG_LIGHT_OFF);
  3539.     }
  3540.     }
  3541.   
  3542.   SDL_UpdateRect(screen, 0, 0, 640, 480);
  3543.   
  3544.   
  3545.   /* Wait for input: */
  3546.   
  3547.   done = 0;
  3548.   quit = 0;
  3549.   
  3550.   do
  3551.     {
  3552.       while (SDL_PollEvent(&event))
  3553.     {
  3554.       if (event.type == SDL_QUIT)
  3555.         {
  3556.           /* Quit event!  */
  3557.           
  3558.           quit = 1;
  3559.         }
  3560.       else if (event.type == SDL_KEYDOWN)
  3561.         {
  3562.           /* A keypress! */
  3563.           
  3564.           done = 1;
  3565.         }
  3566.       else if (event.type == SDL_MOUSEBUTTONDOWN)
  3567.         {
  3568.           /* A mouseclick! */
  3569.           
  3570.           done = 1;
  3571.         }
  3572.     }
  3573.       
  3574.       SDL_Delay(30);
  3575.       
  3576.       
  3577.       /* Keep playing music: */
  3578.       
  3579. #ifndef NOSOUND
  3580.       if (use_sound == 1)
  3581.     {
  3582.       if (!Mix_PlayingMusic())
  3583.         {
  3584.           Mix_PlayMusic(mus_hiscreen, 0);
  3585.           Mix_VolumeMusic((music_vol * MIX_MAX_VOLUME) / 3);
  3586.         }
  3587.     }
  3588. #endif
  3589.  
  3590.     }
  3591.   while (!done && !quit);
  3592.  
  3593.  
  3594.   /* Stop music: */
  3595.   
  3596. #ifndef NOSOUND
  3597.   if (use_sound == 1)
  3598.     Mix_HaltMusic();
  3599. #endif
  3600.  
  3601.   
  3602.   return(quit);
  3603. }
  3604.  
  3605.  
  3606. /* Pause screen: */
  3607.  
  3608. int pausescreen(void)
  3609. {
  3610.   SDL_Event event;
  3611.   SDLKey key;
  3612.   int done, quit;
  3613.   
  3614.   
  3615.   /* Stop music: */
  3616.   
  3617. #ifndef NOSOUND
  3618.   if (use_sound)
  3619.     {
  3620.       Mix_PauseMusic();
  3621.     }
  3622. #endif
  3623.   
  3624.   
  3625.   /* Display "PAUSED" Message: */
  3626.   
  3627.   drawfuzz(224, 224, 192, 32);
  3628.   drawtext(224, 224, "PAUSED");
  3629.   SDL_UpdateRect(screen, 224, 224, 192, 32);
  3630.   
  3631.   
  3632.   /* Wait for keypress: */
  3633.   
  3634.   done = 0;
  3635.   quit = 0;
  3636.   
  3637.   do
  3638.     {
  3639.       while (SDL_PollEvent(&event))
  3640.     {
  3641.       if (event.type == SDL_QUIT)
  3642.         {
  3643.           /* Quit event!  */
  3644.           
  3645.           quit = 2;
  3646.         }
  3647.       else if (event.type == SDL_KEYDOWN)
  3648.         {
  3649.           /* A keypress! */
  3650.  
  3651.               key = event.key.keysym.sym;
  3652.  
  3653.           if (key == SDLK_SPACE || key == SDLK_TAB ||
  3654.           key == SDLK_p)
  3655.         {
  3656.           /* SPACE, TAB or P: Pause! */
  3657.           
  3658.           done = 1;
  3659.         }
  3660.           else if (key == SDLK_ESCAPE)
  3661.         {
  3662.           /* ESCAPE: Quit! */
  3663.           
  3664.           quit = 1;
  3665.         }
  3666.         }
  3667.     }
  3668.     }
  3669.   while (quit == 0 && done == 0);
  3670.   
  3671.   
  3672.   /* Erase message: */
  3673.   
  3674.   erase(224, 224, 192, 32, IMG_BACKGROUND_0);
  3675.   SDL_UpdateRect(screen, 224, 224, 192, 32);
  3676.  
  3677.  
  3678.   /* Unpause music: */
  3679.   
  3680. #ifndef NOSOUND
  3681.   if (use_sound)
  3682.     {
  3683.       Mix_ResumeMusic();
  3684.     }
  3685. #endif
  3686.   
  3687.   
  3688.   return(quit);
  3689. }
  3690.  
  3691.  
  3692. /* Determine user's initials: */
  3693.  
  3694. void getinitials(void)
  3695. {
  3696.   int i;
  3697. #ifdef LINUX
  3698.   struct passwd * pw;
  3699. #endif
  3700.   char * tmp;
  3701.   
  3702.   
  3703.   /* Default to nothing: */
  3704.   
  3705.   for (i = 0; i < 3; i++)
  3706.     username_initials[i] = '\0';
  3707.   
  3708.   
  3709. #ifdef LINUX
  3710.   if (getenv("USER") != NULL)
  3711.     {
  3712.       pw = getpwnam(getenv("USER"));
  3713.       
  3714.       if (pw != NULL && pw->pw_gecos != NULL && strlen(pw->pw_gecos) != 0)
  3715.     {
  3716.       /* Grab initials from real name: */
  3717.       
  3718.       /* First initial (easy!) */
  3719.       
  3720.       username_initials[0] = toupper(pw->pw_gecos[0]);
  3721.       
  3722.       
  3723.       /* Second initial (after first space): */
  3724.       
  3725.       for (i = 0; (i < strlen(pw->pw_gecos) &&
  3726.                username_initials[1] == '\0'); i++)
  3727.         {
  3728.           if (pw->pw_gecos[i] == ' ')
  3729.         username_initials[1] = toupper(pw->pw_gecos[i + 1]);
  3730.         }
  3731.       
  3732.       
  3733.       /* Third initial (next space): */
  3734.       
  3735.       for (i = i; (i < strlen(pw->pw_gecos) &&
  3736.                username_initials[2] == '\0'); i++)
  3737.         {
  3738.           if (pw->pw_gecos[i] == ' ')
  3739.         username_initials[2] = toupper(pw->pw_gecos[i + 1]);
  3740.         }
  3741.     }
  3742.       else
  3743.     {
  3744.       /* Grab initials from username: */
  3745.       
  3746.       tmp = getenv("USER");
  3747.       
  3748.       for (i = 0; i < 3 && i < strlen(tmp); i++)
  3749.         {
  3750.           username_initials[i] = toupper(tmp[i]);
  3751.         }
  3752.     }
  3753.     }
  3754. #endif
  3755. }
  3756.